样例未过求条
查看原帖
样例未过求条
1038334
wth2026楼主2024/5/23 14:57
#include <iostream>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <vector>

#define endl '\n'
#define int long long
#define inf 0x3f3f3f3f
#define lnf 0x3f3f3f3f3f3f3f3f

using namespace std;

//#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1 ++)
//char *p1, *p2, buf[(1 << 20) + 5];
//
//inline int read() {
//	int x = 0;
//	char c = gc();
//	
//	while (!isdigit(c)) {
//		c = gc();
//	}
//	
//	while (isdigit(c)) {
//		x = (x << 3) + (x << 1) + (c ^ 48);
//		c = gc();
//	}
//	
//	return x;
//}
//
//void write(int k) {
//	if (k > 9) {
//		write(k / 10);
//	}
//	
//	putchar(k % 10 + 48);
//}
//
const int N = 4e5;

void init();

int n, m, opt, u, c, in[N + 5], l[N + 5], r[N + 5], cnt;
vector<int> son[N + 5];

struct Segment_Tree {
	int mid;
	
	struct Tree_Node {
		int l, r, flag;
		bitset<64> val;
	} tr[(N << 2) + 5];
	
	void Push_Up(int k) {
		tr[k].val = tr[k << 1].val | tr[k << 1 | 1].val;
	}
	
	void Push_Down(int k) {
		if (tr[k].flag) {
			tr[k].val.reset();
			tr[k].val[tr[k].flag] = 1;
			tr[k << 1].flag = tr[k << 1 | 1].flag = tr[k].flag;
			tr[k << 1].val.reset();
			tr[k << 1 | 1].val.reset();
			tr[k << 1].val[tr[k].flag] = tr[k << 1 | 1].val[tr[k].flag] = 1;
			tr[k].flag = 0;
		}
	}
	
	void Build(int k, int l, int r) {
//		cout << "Build:k=" << k << ",l=" << l << ",r=" << r << ";\n";
		tr[k].l = l;
		tr[k].r = r;
		tr[k].flag = 0;
		tr[k].val.reset();
		
		if (l == r) {
			tr[k].val[in[l]] = 1;
			return;
		}
		
		mid = (l + r) >> 1;
		Build(k << 1, l, mid);
		Build(k << 1 | 1, mid + 1, r);
		Push_Up(k);
	}
	
	void Section_Edit(int k, int l, int r, int x) {
		if (tr[k].r < l || tr[k].l > r) {
			return;
		}
		
		cout << "Section_Edit:k=" << k << ",l=" << l << ",r=" << r << ",x=" << x << ",tr[k].l=" << tr[k].l << ",tr[k].r=" << tr[k].r << ";\n";
		
		if (l <= tr[k].l && tr[k].r <= r) {
			tr[k].flag = x;
			return;
		}
		
		mid = (l + r) >> 1;
		Push_Down(k);
		
		if (l <= mid) {
			Section_Edit(k << 1, l, r, x);
		}
		
		if (r > mid) {
			Section_Edit(k << 1 | 1, l, r, x);
		}
		
		Push_Up(k);
	}
	
	bitset<64> Section_Inquire(int k, int l, int r) {
		bitset<64> ans;
		ans.reset();
		
		if (tr[k].r < l || tr[k].l > r) {
			return ans;
		}
		
//		cout << "Section_Inquire:k=" << k << ",l=" << l << ",r=" << r << ",tr[k].l=" << tr[k].l << ",tr[k].r=" << tr[k].r << ";\n";
//		
		if (l <= tr[k].l && tr[k].r <= r) {
			return tr[k].val;
		}
		
		ans.reset();
		mid = (l + r) >> 1;
		Push_Down(k);
		
		if (l <= mid) {
			ans |= Section_Inquire(k << 1, l, r);
		}
		
		if (r > mid) {
			ans |= Section_Inquire(k << 1 | 1, l, r);
		}
		
		return ans;
	}
} a;

void DFS(int k) {
	l[k] = ++ cnt;
//	cout << "DFS:k=" << k << ",cnt=" << cnt << ";\n";
	
	for (auto it : son[k]) {
//		cout << "DFS_son:it=" << it << ",k=" << k << ",son[k][it]=" << son[k][it] << ";\n";
		DFS(it);
	}
	
	r[k] = cnt;
//	cout << "DFS_lr:k=" << k << ",l[k]=" << l[k] << ",r[k]=" << r[k] << ";\n";
}

signed main() {
	init();
	cin >> n >> m;
//	n = read();
//	m = read();
	
	for (int i = 1; i <= n; ++ i) {
		cin >> in[i];
//		in[i] = read();
	}
	
	a.Build(1, 1, n);
	
	for (int i = 1; i < n; ++ i) {
		cin >> u >> c;
//		u = read();
//		c = read();
		son[u].push_back(c);
	}
	
	DFS(1);
	
	while (m --) {
		cin >> opt >> u;
//		opt = read();
//		u = read();
		
		if (opt == 1) {
			cin >> c;
//			c = read();
			a.Section_Edit(1, l[u], r[u], c);
		} else {
			cout << a.Section_Inquire(1, l[u], r[u]).count() << endl;
//			write(a.Section_Inquire(1, l[u], r[u]).count());
//			puts("");
		}
	}
	
	return 0;
}

void init() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
}

代码重构以后就AC了,但是还是很疑惑这到底哪里错了。

2024/5/23 14:57
加载中...