社区讨论
带修莫队求调
P1903【模板】带修莫队 / [国家集训队] 数颜色 / 维护队列参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lo99yypc
- 此快照首次捕获于
- 2023/10/28 07:59 2 年前
- 此快照最后确认于
- 2023/10/28 07:59 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
#define Reimu inline void // 灵梦赛高
#define Marisa inline int // 魔理沙赛高
#define Sanae inline bool // 早苗赛高
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> Pii;
typedef tuple<int, int, int> Tiii;
#define fi first
#define se second
namespace FastInput {
template<typename Ty>
Reimu read(Ty &x) { // 默认读入整型 int, LL, Uint, ULL, ...
x = 0;
int f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= c == '-';
for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
if (f) x = -x;
}
template<>
Reimu read(double &x) { // 读入浮点型 double
x = 0;
int f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= c == '-';
for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
if (c == '.') {
double e = 1;
for (c = getchar(); isdigit(c); c = getchar()) x += (c ^ 48) * (e *= .1);
}
if (f) x = -x;
}
template<>
Reimu read(char &c) { // 读入字符 char
do c = getchar(); while (!isgraph(c));
}
template<>
Reimu read(string &s) { // 读入字符串 string
s = "";
char c = getchar();
while (!isgraph(c)) c = getchar();
for (; isgraph(c); c = getchar()) s += c;
}
template<typename Ty, typename...Args>
Reimu read(Ty &x, Args &...args) { // 不定长传参
read(x);
read(args...);
}
}
using namespace FastInput; // 使用快读
const int N = 150010;
struct Que { int l, r, ti, k; } q[N];
int n, m, qC, answer;
int col[N], loc[N], oth[N], ans[N], c[N];
Reimu add(int x) { answer += !c[x]++; }
Reimu del(int x) { answer -= !--c[x]; }
Reimu mov(int x, int i) { if (x >= q[i].l && x <= q[i].r) { del(col[loc[x]]); add(oth[x]); } swap(col[loc[x]], oth[x]); }
Reimu solve() {
sort(q + 1, q + qC + 1, [](Que a, Que b) { return a.l < b.l; });
int len1 = pow(qC, 2. / 3), c1 = (qC - 1) / len1 + 1;
for (int i = 1; i <= c1; ++i) {
int l1 = len1 * (i - 1) + 1, r1 = i == c1 ? qC : len1 * i;
sort(q + l1, q + r1 + 1, [](Que a, Que b) { return a.r < b.r; });
int len2 = sqrt(r1 - l1 + 1), c2 = (r1 - l1) / len2 + 1;
for (int j = 1; j <= c2; ++j) {
int l2 = l1 + len2 * (j - 1), r2 = j == c2 ? r1 : l1 + len2 * j - 1;
sort(q + l2, q + r2 + 1, [](Que a, Que b) { return a.ti < b.ti; });
}
}
for (int i = 1, l = 1, r = 0, ti = 0; i <= qC; ++i) {
while (r < q[i].r) add(col[++r]);
while (l > q[i].l) add(col[--l]);
while (r > q[i].r) del(col[r--]);
while (l < q[i].l) del(col[l++]);
while (ti < q[i].ti) mov(++ti, i);
while (ti > q[i].ti) mov(ti--, i);
ans[q[i].k] = answer;
}
}
int main() {
read(n, m);
for (int i = 1; i <= n; ++i) read(col[i]);
for (int i = 1, ti = 0, x, y; i <= m; ++i) {
char c; read(c, x, y);
if (c == 'Q') q[++qC] = {x, y, ti, qC};
else {
++ti;
loc[ti] = x;
oth[ti] = y;
}
}
solve();
for (int i = 1; i <= qC; ++i) printf("%d\n", ans[i]);
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...