社区讨论
为什么将快读数组长度从 $10$ 调到 $9$ 就错了?
P4690[Ynoi Easy Round 2016] 镜中的昆虫参与者 3已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mhjaf7fz
- 此快照首次捕获于
- 2025/11/03 23:21 4 个月前
- 此快照最后确认于
- 2025/11/03 23:21 4 个月前
为什么将下面这份代码的快读缓冲数组长度从 调到 就错了?
如果是 在本地就会输出乱码。
CPP#include <bits/stdc++.h>
const int N = 1e5 + 5;
const int V = 4e5;
const int Sz = 10;
char buf[Sz], *p1, *p2;
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, Sz, stdin), p1 == p2) ? 0 : *p1++)
inline int read() {
int x = 0; char c = gc();
while (!isdigit(c)) c = gc();
while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = gc();
return x;
}
char pbuf[Sz]; int C;
inline void flush() { fwrite(pbuf, 1, C, stdout); C = 0; }
inline void write(char c) { pbuf[C++] = c; if (c == Sz) flush(); }
inline void write(int x) { if (x > 9) write(x / 10); write(char(x % 10 ^ 48)); }
int n, m, a[N], ans[N];
int tmp[N << 1], tot;
struct Que { int op, l, r, x; } que[N];
// set
struct DS {
int r, k, pre, L, R;
bool operator< (DS b) const { return r < b.r; }
};
std::set<int> buc[N << 1];
std::set<DS> set;
// cdq
int cnt;
struct CDQ { int a, b, c, op, id; } num[N * 15], num2[V + 5];
// set
inline int _pre(int x, int k) { return *--buc[k].lower_bound(x); }
inline void update(int r, int pre, int t) {
auto pos = set.lower_bound({r});
auto p = *pos;
if (t >= 0 && r >= 1 && r <= n) {
num[++cnt] = {p.pre + 1, p.r, p.L, 1, 0};
num[++cnt] = {p.pre + 1, p.r, t + 1, -1, 0};
// printf("arr: r:%d pre:%d L:%d R:%d\n", p.r, p.pre, p.L, t);
}
p.pre = pre; p.L = t + 1;
set.erase(pos);
set.insert(p);
}
inline void insert(int l, int r, int k, int L, int R) {
update(*buc[k].upper_bound(r), r, L - 1);
set.insert({r, k, _pre(r, k), L, R}); buc[k].insert(r);
}
// set
inline void erase(std::set<DS>::iterator p, int t) {
// printf("arr: r:%d pre:%d L:%d R:%d\n", p->r, p->pre, p->L, t);
num[++cnt] = {p->pre + 1, p->r, p->L, 1, 0};
num[++cnt] = {p->pre + 1, p->r, t + 1, -1, 0};
buc[p->k].erase(p->r);
update(*buc[p->k].lower_bound(p->r), _pre(p->r, p->k), t);
set.erase(p);
}
inline void split(int r, int t) {
auto pos = set.lower_bound({r});
if (pos->r == r) return;
auto p = *pos;
buc[p.k].insert(r);
set.erase(pos);
set.insert({r, p.k, p.pre, p.L, p.R});
set.insert({p.r, p.k, r, p.L, p.R});
}
// bit
int tr[N], res;
inline void add(int x, int k){ for (++x; x <= m + 2; x += x & -x) tr[x] += k; }
inline int ask(int x) { for (res = 0, ++x; x; x ^= x & -x) res += tr[x]; return res; }
// cdq
bool cmp(CDQ x, CDQ y) { return x.b != y.b ? x.b < y.b : x.id < y.id; }
inline void cdq(int l, int r) {
if (l == r) return;
int mid = l + r >> 1;
cdq(l, mid); cdq(mid + 1, r);
int i = l;
// printf(">> %d %d\n", l, r);
for (int j = mid + 1; j <= r; ++j) {
while (i <= mid && num[i].b <= num[j].b) { if (!num[i].id) add(num[i].c, num[i].op)/*, printf("add:%d %d\n", num[i].c, num[i].op)*/; ++i; }
if (num[j].id) {
ans[num[j].id] += ask(num[j].c) * num[j].op;
if (num[j].id == 1) {
// printf("# %d\n", ask(num[j].c));
}
}
}
while (--i >= l) if (!num[i].id) add(num[i].c, -num[i].op);
// for (int i = 1; i <= m; ++i) if (ask(i)) puts("666666666");
if (l == r) return;
if (l != 1 || r != n) {
if (r - l + 1 > V || r - l + 1 < 100) {
std::sort(num + l, num + r + 1, cmp);
return;
}
int i = l, j = mid + 1, k = -1;
while (i <= mid && j <= r) {
while (i <= mid && j <= r && cmp(num[i], num[j])) num2[++k] = num[i++];
while (i <= mid && j <= r && !cmp(num[i], num[j])) num2[++k] = num[j++];
}
while (i <= mid) num2[++k] = num[i++];
while (j <= r) num2[++k] = num[j++];
for (int i = l; i <= r; ++i) num[i] = num2[i - l];
}
}
int main()
{
n = read(); m = read();
set.insert({0, 0, 0, 0, 0});
set.insert({n + 1, 0, 0, 0, 0});
for (int i = 1; i <= n; ++i) tmp[++tot] = a[i] = read();
for (int i = 1; i <= m; ++i) {
que[i].op = read(); que[i].l = read(); que[i].r = read();
if (que[i].op == 1) tmp[++tot] = que[i].x = read();
}
std::sort(tmp + 1, tmp + 1 + tot);
tot = std::unique(tmp + 1, tmp + 1 + tot) - tmp - 1;
for (int i = 1; i <= n; ++i)
a[i] = std::lower_bound(tmp + 1, tmp + 1 + tot, a[i]) - tmp;
for (int i = 1; i <= m; ++i)
que[i].x = std::lower_bound(tmp + 1, tmp + 1 + tot, que[i].x) - tmp;
// puts("");
// for (int i = 1; i <= n; ++i) printf("%d ", a[i]); puts("");
// for (int i = 1; i <= m; ++i) {
// printf("%d %d %d ", que[i].op, que[i].l, que[i].r);
// if (que[i].op == 1) printf("%d", que[i].x);
// puts("");
// }
for (int i = 1; i <= tot; ++i) buc[i].insert(0), buc[i].insert(n + 1);
for (int i = 1; i <= n; ++i)
insert(i, i, a[i], 0, m);
int count = 0;
for(int i = 1; i <= m; ++i) {
int op = que[i].op, l = que[i].l, r = que[i].r, x = que[i].x;
if (que[i].op == 1) {
split(r, i); split(l - 1, i);
std::set<DS>::iterator p;
while (( p = set.lower_bound({l}) )->r <= r) erase(p, i - 1);
insert(l, r, x, i, m);
} else {
split(r, i); split(l - 1, i);
++count;
num[++cnt] = {l, r, i, 1, count};
num[++cnt] = {l, l - 1, i, -1, count};
// printf("que: l:%d r:%d t:%d\n", l, r, i);
}
}
for (auto p : set) {
if (!p.r || p.r > n) continue;
num[++cnt] = {p.pre + 1, p.r, p.L, 1, 0};
num[++cnt] = {p.pre + 1, p.r, m + 1, -1, 0};
// printf("arr: r:%d pre:%d L:%d R:%d\n", p.r, p.pre, p.L, m);
}
std::sort(num + 1, num + 1 + cnt, [](CDQ x, CDQ y){ return x.a != y.a ? x.a < y.a : x.id < y.id; });
// puts("");
// for (int i = 1; i <= cnt; ++i) {
// if (num[i].a <= num[1].a && num[i].b <= num[1].b && num[i].c <= num[1].c) putchar('!');
// printf("%d %d %d %d %d\n", num[i].a, num[i].b, num[i].c, num[i].op, num[i].id);
// }
// puts("");
cdq(1, cnt);
for (int i = 1; i <= count; ++i) write(ans[i]), write('\n');
flush();
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...