求助
查看原帖
求助
127925
Kio_楼主2020/11/5 17:37

思路和题解差不多,就是把树上的节点扔到dfs序上处理,重链剖分,并拿线段树来维护区间覆盖、区间求和的操作。

没过样例......求大佬答疑qwq

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int n;
vector<int> tree[100020];
int cnt[100020],dfn[100020],dl,pos[100020],hson[100020],fa[100020],top[100020],dep[100020];
inline void swap(int &a,int &b){a^=b;b^=a;a^=b;}
inline int abs(int a){return a<0?-a:a;}
void dfs1(int x,int d){
	cnt[x] = 1;
	dep[x] = d;
	for(int i=0;i<tree[x].size();i++){
		int v = tree[x][i];
		fa[v] = x;
		dfs1(v,d+1);
		cnt[x] += cnt[v];
		if(cnt[hson[x]] < cnt[v]) hson[x] = v;
	}
}
void dfs2(int x,int tp){
	dfn[x] = ++dl;
	pos[dl] = x;
	top[x] = tp;
	if(hson[x]) dfs2(hson[x],tp);
	for(int i=0;i<tree[x].size();i++){
		int v = tree[x][i];
		if(v!=hson[x]) dfs2(v,v);
	}
}
struct ivaltree{
	int value[4*100010],lazy[4*100010];
	void build(int l,int r,int a){
		lazy[a] = -1;
		value[a] = 0;
		if(l==r) return;
		int mid = (l+r)>>1;
		build(l,mid,a<<1);
		build(mid+1,r,a<<1|1);
	}
	inline void push_down(int l,int r,int a){
		int mid = (l+r)>>1;
		value[a<<1] = lazy[a]*(mid-l+1);
		value[a<<1|1] = lazy[a]*(r-mid);
		lazy[a<<1] = lazy[a];
		lazy[a<<1|1] = lazy[a];
		lazy[a] = -1;
	}
	inline void update(int a){value[a] = value[a<<1] + value[a<<1|1];}
	void fugai(int L,int R,int l,int r,int a,int v){
		if(L<=l&&r<=R){
			lazy[a] = v;
			value[a] = (r-l+1)*v;
			return;
		}
		if(lazy[a]!=-1)push_down(l,r,a);
		int mid = (l+r)>>1;
		if(L<=mid) fugai(L,R,l,mid,a<<1,v);
		if(mid+1<=R) fugai(L,R,mid+1,r,a<<1|1,v);
		update(a);
	}
	int sum(int L,int R,int l,int r,int a){
		if(L<=l&&r<=R) return value[a];
		int ans=0;
		if(lazy[a]!=-1)push_down(l,r,a);
		int mid = (l+r)>>1;
		if(L<=mid) ans += sum(L,R,l,mid,a<<1);
		if(mid+1<=R) ans += sum(L,R,mid+1,r,a<<1|1);
		update(a);
		return ans;
	}
	void change(int l,int r,int a,int v){
		int x=l,y=r;
		while(top[x]!=top[y]){
			if(dep[top[x]] < dep[top[y]]) swap(x,y);
			fugai(dfn[top[x]],dfn[x],1,n,1,v);
			x = fa[top[x]];
		}
		if(dep[x] > dep[y]) swap(x,y);
		fugai(dfn[x],dfn[y],1,n,1,v);
		update(a);
	}
}itree;
int read(){
	int num=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while('0'<=c&&c<='9') num=num*10+c-'0',c=getchar();
	return num;
}
int main(){
	n=read();
	for(int i=2;i<=n;i++){
		int a=read();
		tree[a+1].push_back(i);
	}
	dfs1(1,1);
	dfs2(1,1);
//	printf("1");
	itree.build(1,n,1);
	int q=read();
	while(q--){
		char c[15];
		scanf("%s",c+1);
		int tmp = itree.value[1];
		if(c[1]=='i'){
			int x = read();
			x++;
			itree.fugai(1,dfn[x],1,n,1,1);
			printf("%d\n",abs(tmp - itree.value[1]));
		}
		else{
			int x = read();
			x++;
			itree.fugai(dfn[x],dfn[x]+cnt[x]-1,1,n,1,0);
			printf("%d\n",abs(tmp - itree.value[1]));
		}
	}
	return 0;
}
2020/11/5 17:37
加载中...