求调20分树剖
查看原帖
求调20分树剖
217634
anonymous217楼主2022/3/20 22:42
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=114514;
int cdfn,cnt=1,n,q,r,p; 
int fa[N],dep[N],Size[N],son[N],t[N],top[N],dfn[N],a[N];
int tree[N*4],tag[N*4],head[N],to[N*2],nxt[N*2];
void pushup(int cur){
	tree[cur]=(tree[cur*2]+tree[cur*2+1])%p;
	return;
}
void addtag(int cur,int lt,int rt,int val){
	tag[cur]=(tag[cur]+val)%p;
	tree[cur]=(tree[cur]+(rt-lt+1)*val)%p;
	return;
}
void build(int cur,int lt,int rt){
	if(lt==rt){
		tree[cur]=a[t[lt]];
		return;
	}
	int mid=(lt+rt)>>1;
	build(cur*2,lt,mid);
	build(cur*2+1,mid+1,rt);
	pushup(cur);
	return;
}
void pushdown(int cur,int lt,int rt){
	if(tag[cur]==0)return;
	int mid=(lt+rt)>>1;
	addtag(2*cur,lt,mid,tag[cur]);
	addtag(2*cur+1,mid+1,rt,tag[cur]);
	tag[cur]=0;
	return;
}
int query(int cur,int lt,int rt,int qx,int qy){
	if(qx>rt||qy<lt)return 0;
	if(qx<=lt&&qy>=rt)return tree[cur];
	pushdown(cur,lt,rt);
	int mid=(lt+rt)>>1;
	return (query(cur*2,lt,mid,qx,qy)+query(cur*2+1,mid+1,rt,qx,qy))%p;
}
void update(int cur,int lt,int rt,int qx,int qy,int val){
	if(qx>rt||qy<lt)return;
	if(qx<=lt&&qy>=rt){
		addtag(cur,lt,rt,val);
		return;
	}
	pushdown(cur,lt,rt);
	int mid=(lt+rt)>>1;
	update(cur*2,lt,mid,qx,qy,val);
	update(cur*2+1,mid+1,rt,qx,qy,val);
	pushup(cur);
	return;
}
void single(int a,int b){
	cnt++;
	to[cnt]=b;
	nxt[cnt]=head[a];
	head[a]=cnt;
	return;
}
void add(int a,int b){
	single(a,b);
	single(b,a);
}
void dfs1(int cur,int Fa,int Dep){
	fa[cur]=Fa;
	dep[cur]=Dep;
	Size[cur]=1;
	for(int i=head[cur];i;i=nxt[i]){
		if(to[i]==Fa)continue;
		dfs1(to[i],cur,Dep+1);
		Size[cur]+=Size[to[i]];
		if(Size[to[i]]>Size[son[cur]])son[cur]=to[i];
	}
}
void dfs2(int cur,int tp){
	cdfn++;
	dfn[cur]=cdfn;
	t[cdfn]=cur;
	top[cur]=tp;
	if(!son[cur])return;
	dfs2(son[cur],tp);
	for(int i=head[cur];i;i=nxt[i]){
		if(to[i]==fa[cur]||to[i]==son[cur])continue;
		dfs2(to[i],to[i]);
	}
}
void addt(int cur,int v){
	update(1,1,n,dfn[cur],dfn[cur]+Size[cur]-1,v);
}
int qut(int cur){
	return query(1,1,n,dfn[cur],dfn[cur]+Size[cur]-1);
}
void addl(int From,int To,int val){
	val%=p;
	while(top[From]!=top[To]){
		if(dep[From]<dep[To])swap(From,To);
		update(1,1,n,dfn[top[From]],dfn[From],val);
		From=fa[top[From]];
	}
	if(dep[From]>dep[To])swap(From,To);
	update(1,1,n,dfn[From],dfn[To],val);
	return;
}
int quel(int From,int To){
	int ans=0;
	while(top[From]!=top[To]){
		if(dep[From]<dep[To])swap(From,To);
		ans=(ans+query(1,1,n,dfn[top[From]],dfn[From]))%p;
		From=fa[top[From]];
	}
	if(dep[From]>dep[To])swap(From,To);
	ans=(ans+query(1,1,n,dfn[From],dfn[To]))%p;
	return ans%p;
}
signed main(){
    cin>>n>>q>>r>>p;
	for(int i=1;i<=n;i++)cin>>a[i];
	int jsad,jfbh;
	for(int i=1;i<n;i++){
		cin>>jsad>>jfbh;
		add(jsad,jfbh);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	for(int i=1;i<=n;i++){
		cout<<i<<":"<<Size[]
	}
	for(int i=1;i<=q;i++){
		int opt,a,b,c;
		cin>>opt>>a;
		if(opt==3){cin>>b;addt(a,b);}
		if(opt==1){cin>>b>>c;addl(a,b,c);}
		if(opt==2){cin>>b;cout<<quel(a,b)<<endl;}
		if(opt==4){cout<<qut(a)<<endl;}
	}
    return 0;
}

一,三点可过,其他全wa

2022/3/20 22:42
加载中...