求助,输出都有问题
查看原帖
求助,输出都有问题
149933
Zero_Legend楼主2021/2/3 11:02

自己实在找不到错了 请大佬看看哪里有问题,谢谢!

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,root,mod;
int idx=1;
int ans1=0,ans2=0;

 struct node{
 	int l;
 	int r;
 	int sum;
 	int lazy;
 }tree[4*N];
 
 int head[N],ver[2*N],nex[2*N],son[N],size[N],f[N],d[N],top[N],id[N],rk[N];
 int input[N];
 int cnt=1;
 
 void add_e(int x,int y){
 	ver[++idx]=y;
 	nex[idx]=head[x];
 	head[x]=idx;
 }
 
 void build(int l,int r,int i){//常规建树 
 	tree[i].l=l;
 	tree[i].r=r;
 	if(l==r){
 		tree[i].sum=input[i]%mod;
 		return ;
	}
	int mid=(l+r)/2;
	build(l,mid,2*i);
	build(mid+1,r,2*i+1);
	tree[i].sum=(tree[2*i].sum+tree[2*i+1].sum)%mod;
 }
 
 void push_down(int i){//延迟标记下移 
 	if(tree[i].lazy){
 		tree[i].sum+=(tree[i].r-tree[i].l+1)* tree[i].lazy;
		tree[2*i].lazy+=tree[i].lazy;
		tree[2*i+1].lazy+=tree[i].lazy;
		tree[i].lazy=0; 
	 }
 }
 
 int ask(int i,int L,int R){//区间查询 
 	if(tree[i].l>=L&&tree[i].r<=R) return tree[i].sum;
 	if(tree[i].lazy)push_down(i);
 	int mid=(tree[i].l+tree[i].r)/2;
 	if(mid>=L) ans1+=ask(2*i,L,R);
 	if(mid<=R) ans1+=ask(2*i+1,L,R);
 	return ans1%mod;
 }
 
 void add(int i,int L,int R,int k){//区间修改 
 	if(tree[i].l>=L&&tree[i].r<=R){
 		tree[i].sum+=(tree[i].r-tree[i].l+1)*k; 
 		tree[i].lazy+=k;
 		return ;
	}
	push_down(i);
	int mid=(tree[i].l+tree[i].r)/2;
	if(mid>=L) add(2*i,L,R,k);
	if(mid<=R) add(2*i+1,L,R,k);
 }
 
 void dfs1(int x,int fa,int depth){//x:当前结点 fa:父结点 depth:当前结点深度 
 	f[x]=fa;//更新父结点 
 	d[x]=depth;//更新深度 
 	size[x]=1;//子树大小初始化:根节点本身 
 	for(int i=head[x];i;i=nex[i]){
 		int y=ver[i];
 		if(y==fa) return ;
 		dfs1(y,x,depth+1);
		if(size[y]>size[son[x]]) son[x]=y;//更新重儿子 
		size[x]+=size[y];//更新子树大小 
	 }
	 return ;
 } 
 
 void dfs2(int u,int t){//u为当前结点,t为链段 
 	top[u]=t;
 	id[u]=++cnt;
 	rk[cnt]=u;//新的编号 
 	if(!son[u]) return ;
 	dfs2(son[u],t);//优先遍历重儿子,使一条链上编号连续 
 	for(int i=head[u];i;i=nex[i]){
 		int y=ver[i];
		if(y==son[u]||y==f[u]) continue; 
		dfs2(y,y);//再建一条链 
	 } 
 }
 
 void func1(int x,int y,int k){//将树从 x到 y结点最短路径上所有节点的值都加上k
 	while(top[x]!=top[y]){//循环,直到这两个点处于同一条链 
 		if(d[top[x]]<d[top[y]]) swap(x,y);//规范 
 		add(1,id[x],id[top[x]],k);
 		x=f[top[x]];
	 }
	 if(d[x]>d[y]) swap(x,y);//深度较浅的一定是序号较小的 
	 add(1,id[x],id[y],k);
 }
 
 void func2(int x,int y){
 	while(top[x]!=top[y]){
 		if(d[top[x]]<d[top[y]]) swap(x,y);
 		ans2+=ask(1,id[x],id[top[x]]);
 		ans1=0;
 		x=f[top[x]];
	 }
	 if(d[x]>d[y]) swap(x,y);//道理同上 
	 ans2+=ask(1,id[x],id[y]);
	 ans1=0;
 }
 
 
int main(){
	cin>>n>>m>>root>>mod;
	for(int i=1;i<=n;i++){
		cin>>input[i];//输入节点初始值 
	}
	for(int i=1;i<=n-1;i++){
		int x,y;
		cin>>x>>y; 
		add_e(x,y);
		add_e(y,x);//建图 
	}
	dfs1(root,0,1);//第一次dfs求son,depth,f,size 
	dfs2(root,root);//第二次dfs求id,rk,将树拆成链表 
	build(1,n,1);//建树 
	for(int i=1;i<=m;i++){
		int type;
		cin>>type;
		if(type==1){
			int x,y,z;
			cin>>x>>y>>z;
			func1(x,y,z);
		}
		if(type==2){
			int x,y;
			cin>>x>>y;
			func2(x,y);
			cout<<ans2<<endl;
			ans2=0; 
		}
		if(type==3){
			int x,z;
			cin>>x>>z;
			func1(id[x],id[x]+size[x]-1,z);
		}
		if(type==4){
			int x;
			cin>>x;
			func2(id[x],id[x]+size[x]-1);
			cout<<ans2<<endl;
			ans2=0;
		}
	} 
	return 0;
}
2021/2/3 11:02
加载中...