社区讨论

萌新95分求助!!!!!!WA第16个点, 求大佬指点

P2146[NOI2015] 软件包管理器参与者 3已保存回复 4

讨论操作

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

当前回复
4 条
当前快照
1 份
快照标识符
@lo2cgeqv
此快照首次捕获于
2023/10/23 11:34
2 年前
此快照最后确认于
2023/11/03 11:43
2 年前
查看原帖
C
#include<bits/stdc++.h>
using namespace std;
//#define LL long long 
const int MAX = 3e5 + 70;
int n, m, q, tot, head[MAX], dep[MAX], id, siz[MAX], in_l[MAX], in_r[MAX];
int num, dfn[MAX], nfd[MAX], bel[MAX], f[MAX];
struct made {
	int l, t;
}edge[MAX * 2];
void add(int u, int v) {
	edge[++tot].l = head[u];
	edge[tot].t = v;
	head[u] = tot;
}
struct SegmentTree {
	int l, r, bol, dat;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define bol(x) tree[x].bol
	#define dat(x) tree[x].dat
}tree[MAX * 4];
char s[MAX];
void dfs_size(int x, int fa) {
	f[x] = fa, siz[x] = 1, dep[x] = dep[fa] + 1;
	for(int i = head[x]; i; i = edge[i].l) {
		int t = edge[i].t;
		if(t == fa) continue;
		dfs_size(t, x);
		siz[x] += siz[t];
	}
}
void dfs(int p, int chain) {
	int k = n + 2; dfn[p] = ++num; bel[p] = chain; nfd[num] = p; in_l[p] = num; 
	for(int i = head[p]; i; i = edge[i].l) {
		int t = edge[i].t;
		if(dep[t] == dep[p] + 1) if(siz[t] > siz[k]) k = t;
	}
	if(k != n + 2) dfs(k, chain);
	for(int i = head[p]; i; i = edge[i].l) {
		int t = edge[i].t;
		if(dep[t] == dep[p] + 1 && t != k) dfs(t, t);
	}
	in_r[p] = num;
}
void build(int p, int l, int r) {
	l(p) = l; r(p) = r; bol(p) = 0, dat(p) = -1; 
	if(l(p) == r(p)) return ;
	int mid = (l + r) / 2;
	build(2 * p, l, mid);
	build(2 * p + 1, mid + 1, r);
}
void spread(int p) {
	if(dat(p) != -1) {
		dat(2 * p) = dat(2 * p + 1) = dat(p);
		bol(2 * p) = (dat(p) == 1 ? (r(2 * p) - l(2 * p) + 1) : 0);
		bol(2 * p + 1) = (dat(p) == 1 ? (r(2 * p + 1) - l(2 * p + 1) + 1) : 0);
		dat(p) = -1; 
	}
}
int find(int p, int l, int r, int val) {
	int ans = 0;
	if(l(p) >= l && r(p) <= r) {
		if(val == 0) return (r(p) - l(p) + 1) - bol(p);
		else return bol(p);
	}
	spread(p);
	int mid = (l(p) + r(p)) / 2;
	if(mid >= r) ans += find(2 * p, l, r, val);
	else if(mid < l) ans += find(2 * p + 1, l, r, val);
	else {
		ans += find(2 * p, l, r, val);
		ans += find(2 * p + 1, l, r, val);
	}
	return ans;
}
void change(int p, int l, int r, int val) {
	if(l(p) >= l && r(p) <= r) {
		if(val == 0) {
			bol(p) = 0;
			dat(p) = 0;	
		} 
		else {
			bol(p) = (r(p) - l(p) + 1);
			dat(p) = 1;	
		}
		return ;
	}
	spread(p);
	int mid = (l(p) + r(p)) / 2;
	if(mid >= r) change(2 * p, l, r, val);
	else if(mid < l) change(2 * p + 1, l, r, val);
	else {
		change(2 * p, l, r, val);
		change(2 * p + 1, l, r, val);
	}
	bol(p) = bol(2 * p) + bol(2 * p + 1);
}
int Q(int u, int v, int val) {
	int ans = 0;
	while(bel[u] != bel[v]) {
		ans += find(1, dfn[bel[u]], dfn[u], 0);
		change(1, dfn[bel[u]], dfn[u], 1);
		u = f[bel[u]];
	}
	ans += find(1, dfn[v], dfn[u], 0);
	change(1, dfn[v], dfn[u], 1);
	return ans;
}
int main() {
//	freopen("manager.in","r",stdin);
//	freopen("manager.out","w",stdout);
	scanf("%d", &n);
	for(int i = 1; i < n; i++)  {
		int v;
		scanf("%d", &v);
		add(v, i);
	}
	dfs_size(0, 0);
	dfs(0, 1);
	build(1, 1, n);
	scanf("%d", &q); 
	for(int i = 1; i <= q; i++) {
		scanf("%s", s + 1);
		scanf("%d", &id);
		if(s[1] == 'i') {
			int ans = Q(id, 0, 0);
			printf("%d\n", ans);
		}
		else {
			int ans = find(1, in_l[id], in_r[id], 1);
			change(1, in_l[id], in_r[id], 0);
			printf("%d\n", ans);
		}
	}
	return 0;
}

回复

4 条回复,欢迎继续交流。

正在加载回复...