社区讨论
带修莫队常数一般是多少?
P4690[Ynoi Easy Round 2016] 镜中的昆虫参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo1be66m
- 此快照首次捕获于
- 2023/10/22 18:17 2 年前
- 此快照最后确认于
- 2023/11/02 18:37 2 年前
rt,我算出来 也就是 2e8,开两秒按道理应该完全能过啊!
然后有人模拟赛放了这题,我写了 暴力+带修莫队+珂朵莉树拿 80 分,这是我的代码:
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
inline int read() {
char c; bool f = true;
while (!isdigit(c = getchar())) f = c != '-';
int x = c ^ 48;
while (isdigit(c = getchar())) x = x * 10 + (c ^ 48);
return f ? x : -x;
}
const int N = 500010;
const int p = 1000000007;
int n, m, a[N];
struct input {
int op, l, r, x, ans, id;
} in[N];
namespace subtask1 {
inline int main() {
for (int i = 1; i <= m; i++) {
if (in[i].op == 1) {
for (int j = in[i].l; j <= in[i].r; j++) {
a[j] = in[i].x;
}
} else {
unordered_set<int> s;
for (int j = in[i].l; j <= in[i].r; j++) {
s.insert(a[j]);
}
printf("%d\n", s.size());
}
}
return 0;
}
}
namespace subtask2 {
int bel[N];
struct query {
int l, r, t, id;
inline bool operator < (const query &x) const {
if (bel[l] == bel[x.l]) {
if (bel[r] == bel[x.r]) {
return (bel[r] & 1) ? (t < x.t) : (t > x.t);
} else {
return (bel[l] & 1) ? (bel[l] < bel[x.l]) : (bel[l] > bel[x.l]);
}
} else {
return bel[l] < bel[x.l];
}
}
} q[N];
int tot, qn, pos[N], u[N], v[N];
int cnt[N], cur;
inline void insert(int x) {
// cout << "insert: " << x << endl;
cnt[x]++;
if (cnt[x] == 1) {
cur++;
}
}
inline void remove(int x) {
// cout << "remove: " << x << endl;
cnt[x]--;
if (cnt[x] == 0) {
cur--;
}
}
int qans[N];
inline int main() {
int t = pow(m, 0.67);
for (int i = 1; i <= m; i++) {
bel[i] = i / t + 1;
}
for (int i = 1; i <= m; i++) {
if (in[i].op == 1) {
tot++;
u[tot] = a[in[i].l];
a[in[i].l] = in[i].x;
v[tot] = a[in[i].l];
pos[tot] = in[i].l;
// cout << "mdf #" << tot << " " << u[tot] << " -> " << v[tot] << endl;
} else {
qn++;
q[qn].l = in[i].l;
q[qn].r = in[i].r;
q[qn].id = qn;
q[qn].t = tot;
}
}
sort(q + 1, q + qn + 1);
int l = 1, r = 0, now = tot;
for (int i = 1; i <= qn; i++) {
// cout << "query: " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].t << " - " << " " << l << " " << r << " " << now << endl;
while (r < q[i].r) insert(a[++r]);
while (l > q[i].l) insert(a[--l]);
while (r > q[i].r) remove(a[r--]);
while (l < q[i].l) remove(a[l++]);
// cout << "query " << q[i].id << " I'm here: " << l << " " << r << endl;
while (now < q[i].t) {
now++;
assert(a[pos[now]] == u[now]);
if (l <= pos[now] && pos[now] <= r) {
remove(a[pos[now]]);
}
a[pos[now]] = v[now];
if (l <= pos[now] && pos[now] <= r) {
insert(a[pos[now]]);
}
}
while (now > q[i].t) {
// cout << "processing modification: " << pos[now] << " " << u[now] << " " << v[now] << endl;
assert(a[pos[now]] == v[now]);
if (l <= pos[now] && pos[now] <= r) {
remove(a[pos[now]]);
}
a[pos[now]] = u[now];
if (l <= pos[now] && pos[now] <= r) {
insert(a[pos[now]]);
}
now--;
}
qans[q[i].id] = cur;
}
for (int i = 1; i <= qn; i++) {
printf("%d\n", qans[i]);
}
return 0;
}
}
namespace subtask3 {
struct segment {
int l, r, v;
inline bool operator < (const segment &x) const {
if (l == x.l) {
return r < x.r;
}
return l < x.l;
}
inline segment(int l, int r, int v): l(l), r(r), v(v) {}
};
set<segment> s;
typedef set<segment>::iterator it;
inline it split(int v) {
if (v > n) return s.end();
// [..., x - 1], [x, ...]
it x = s.lower_bound(segment(v, 0, 0));
if (x == s.end() || x -> l > v) {
x--;
assert(x -> l < v);
segment sg = *x;
s.erase(x);
s.insert(segment(sg.l, v - 1, sg.v));
return s.insert(segment(v, sg.r, sg.v)).first;
} else {
if (x -> l == x -> r) {
assert(x -> l == v);
return x;
} else {
return x;
// segment sg = *x;
// s.erase(x);
// s.insert(segment(sg.l, v - 1, sg.v));
// return s.insert(segment(v, sg.r, sg.v)).first;
}
}
}
inline void spread(it x) {
segment sg = *x;
bool success = false;
if (x != s.begin()) {
it pre = x;
--pre;
if (pre -> v == x -> v) {
sg.l = pre -> l;
s.erase(pre);
success = true;
}
}
if (x != --s.end()) {
it nxt = x;
++nxt;
if (nxt -> v == x -> v) {
sg.r = nxt -> r;
s.erase(nxt);
success = true;
}
}
if (success) {
s.erase(x);
s.insert(sg);
}
}
inline void assign(int L, int R, int v) {
it r = split(R + 1), l = split(L);
// cout << "assign: " << L << " " << R << " " << v << " " << (l == r) << endl;
while (l != r) {
// cout << "l: [" << (l -> l) << ", " << (l -> r) << "], r: [" << (r -> l) << ", " << (r -> r) << "]" << endl;
// s.erase(l);
it cpy = l;
l++;
s.erase(cpy);
}
// exit(0);
spread(s.insert(segment(L, R, v)).first);
}
inline int query(int L, int R) {
unordered_set<int> s;
it r = split(R + 1), l = split(L);
while (l != r) {
s.insert(l -> v);
l++;
}
return s.size();
}
inline void print() {
for (it i = s.begin(); i != s.end(); i++) {
printf("[%d, %d]: %d, ", i -> l, i -> r, i -> v);
}
puts("");
}
inline int main() {
for (int i = 1; i <= n; i++) {
spread(s.insert(segment(i, i, a[i])).first);
}
for (int i = 1; i <= m; i++) {
// cout << "op #" << i << endl;
// print();
if (in[i].op == 1) {
assign(in[i].l, in[i].r, in[i].x);
} else {
printf("%d\n", query(in[i].l, in[i].r));
}
}
return 0;
}
}
vector<int> v;
int main() {
// freopen("D.in", "r", stdin);
// freopen("D.out", "w", stdout);
n = read(); m = read();
for (int i = 1; i <= n; i++) {
a[i] = read();
v.push_back(a[i]);
}
bool toggle1 = true;
for (int i = 1; i <= m; i++) {
in[i].op = read();
if (in[i].op == 1) {
in[i].l = read();
in[i].r = read();
in[i].x = read();
v.push_back(in[i].x);
toggle1 &= (in[i].l == in[i].r);
} else {
in[i].l = read();
in[i].r = read();
}
}
sort(v.begin(), v.end());
for (int i = 1; i <= n; i++) {
a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;
}
for (int i = 1; i <= m; i++) {
if (in[i].op == 1) {
in[i].x = lower_bound(v.begin(), v.end(), in[i].x) - v.begin() + 1;
}
}
// bool debug = true;
bool debug = false;
if (n <= 1000 && m <= 1000 && !debug) {
return subtask1::main();
} else if (toggle1) {
return subtask2::main();
} else {
// cerr << "sb" << endl;
return subtask3::main();
}
}
/*
10 10
9 9 0 9 8 7 10 8 6 7
1 6 8 4
1 1 1 1
1 3 10 2
1 2 3 0
2 1 3
2 1 8
2 6 6
1 1 2 0
1 8 9 7
2 6 7
10 10
6 0 9 7 5 7 4 5 10 6
2 9 10
2 1 3
1 2 5 4
2 3 3
2 1 10
2 3 7
1 1 10 7
2 4 9
1 1 6 5
2 7 9
2
3
1
5
2
1
1
5 5
1 2 3 4 5
2 1 3
2 2 5
1 4 4 3
2 2 5
2 4 5
3
4
3
2
1 2 3 3 5
10 10
315300 924016 265298 633282 540235 874286 367789 74037 87457 345556
1 5 5 934930
1 5 5 502435
1 5 5 144462
2 4 5
2 1 8
2 7 8
2 3 6
1 10 10 5819
1 2 2 480922
2 9 10
5 5
1 2 3 4 5
2 1 5
1 2 3 4
2 1 5
2 3 3
2 2 4
2
8
2
4
2
20 20
4 1 2 0 2 4 3 0 1 4 1 1 4 1 4 1 2 1 2 1
1 2 2 0
1 3 3 3
1 4 4 2
2 1 1
2 2 5
1 1 1 1
1 3 3 3
1 1 1 4
2 1 3
2 1 5
1 2 2 4
2 1 3
2 1 4
1 2 2 0
2 1 2
1 3 3 2
1 1 1 3
2 1 3
1 1 1 2
1 3 3 3
1
3
3
4
2
3
2
3
10 2
6 7 10 1 1 1 1 0 4 8
1 9 2 5
2 3 6
*/
只看
subtask2(莫队)部分就行,是我复杂度写假了还是带修莫队常数大?回复
共 4 条回复,欢迎继续交流。
正在加载回复...