讨论区唯一过样例但是全wa的?
查看原帖
讨论区唯一过样例但是全wa的?
469066
zzxLLL楼主2021/8/28 23:38
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+10;
int n,m,r,p,w[M];
struct edgenode{int to,next;}edge[M<<1];
int head[M],cnte;
void add(int u,int v){
	edge[++cnte].to=v;
	edge[cnte].next=head[u];
	head[u]=cnte;
}
//树剖 
int depth[M],fa[M],son[M],size[M];
void dfs1(int u,int f){
	fa[u]=f;
	size[u]=1;
	depth[u]=depth[f]+1;
	for(int i=head[u];~i;i=edge[i].next){
		int v=edge[i].to;
		if(v==f) continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]]) son[u]=v;
	}
}
int top[M],id[M],rev[M],cnt;
void dfs2(int u){
	id[u]=++cnt,rev[cnt]=u;
	if(u==son[fa[u]]) top[u]=top[fa[u]];
	else top[u]=u;
	for(int i=head[u];~i;i=edge[i].next){
		int v=edge[i].to;
		if(v!=fa[u]) dfs2(v);
	}
}
//线段树
struct segmenttree{int l,r,val,lazy;}tree[M<<2];
void pushup(int k){tree[k].val=(tree[k<<1].val+tree[k<<1|1].val)%p;}
void pushdown(int k){
	if(tree[k].lazy==0) return;
	tree[k<<1].val=(tree[k<<1].val+tree[k].lazy*(tree[k<<1].r-tree[k<<1].l+1))%p;
	tree[k<<1|1].val=(tree[k<<1|1].val+tree[k].lazy*(tree[k<<1|1].r-tree[k<<1|1].l+1))%p;
	tree[k<<1].lazy=(tree[k<<1].lazy+tree[k].lazy)%p;
	tree[k<<1|1].lazy=(tree[k<<1|1].lazy+tree[k].lazy)%p;
	tree[k].lazy=0;
}
void build(int k,int l,int r){
	tree[k].l=l,tree[k].r=r;
	if(l==r){
		tree[k].val=w[id[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	pushup(k);
}
void update(int l,int r,int k,int val){
	if(tree[k].l>=l&&tree[k].r<=r){
		tree[k].val=(tree[k].val+val*(tree[k].r-tree[k].l+1))%p;
		tree[k].lazy=(tree[k].lazy+val)%p;
		return;
	}
	pushdown(k);
	int mid=(tree[k].l+tree[k].r)>>1;
	if(mid>=l) update(l,r,k<<1,val);
	if(mid<r) update(l,r,k<<1|1,val);
	pushup(k);
}
int query(int l,int r,int k){
	if(tree[k].l>=l&&tree[k].r<=r) return tree[k].val;
	pushdown(k);
	int mid=(tree[k].l+tree[k].r)>>1,sum=0;
	if(mid>=l) sum+=query(l,r,k<<1);
	if(mid<r) sum+=query(l,r,k<<1|1);
	return sum%p;
}
void chainupdate(int u,int v,int val){
	while(top[u]!=top[v]){
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		update(id[top[u]],id[u],1,val);
		u=fa[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	update(id[u],id[v],1,val);
}
int chainquery(int u,int v){
	int sum=0;
	while(top[u]!=top[v]){
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		sum=(sum+query(id[top[u]],id[u],1))%p;
		u=fa[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	sum=(sum+query(id[u],id[v],1))%p;
	return sum;
}
void print(){
    for(int i=1;i<=n;i++) printf("%d ",query(i,i,1));
    putchar('\n');
}
int main(){
	for(int i=0;i<M;i++) head[i]=-1;
	scanf("%d%d%d%d",&n,&m,&r,&p);
	for(int i=1;i<=n;i++) scanf("%d",&w[i]);
	for(int i=1,x,y;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
	dfs1(r,0),dfs2(r);
	build(1,1,n);
	for(int i=1,op,x,y,z;i<=m;i++){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&x,&y,&z);
			chainupdate(x,y,z%p);
		}
		if(op==2){
			scanf("%d%d",&x,&y);
			printf("%d\n",chainquery(x,y));
		}
		if(op==3){
			scanf("%d%d",&x,&z);
			update(id[x],id[x]+size[x]-1,1,z%p);
		}
		if(op==4){
			scanf("%d",&x);
			printf("%d\n",query(id[x],id[x]+size[x]-1,1));
		}
		//print();
	}
	return 0;
}
2021/8/28 23:38
加载中...