社区讨论

为什么将快读数组长度从 $10$ 调到 $9$ 就错了?

P4690[Ynoi Easy Round 2016] 镜中的昆虫参与者 3已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@mhjaf7fz
此快照首次捕获于
2025/11/03 23:21
4 个月前
此快照最后确认于
2025/11/03 23:21
4 个月前
查看原帖
为什么将下面这份代码的快读缓冲数组长度从 1010 调到 99 就错了?
如果是 99 在本地就会输出乱码。
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 条回复,欢迎继续交流。

正在加载回复...