37分求调
查看原帖
37分求调
1040353
zhangshirui楼主2023/12/28 16:41
#include<bits/stdc++.h>
using namespace std;
#define ll long long
long long n,m,s,r; 
#include<bits/stdc++.h>
using namespace std;
const long long N=100005;
struct node{
	long long sum=0,tag_abb=0,tag_mul=1,tag_set=0,l,r,mid;bool can_tag_set=0;//l~mid,mid+1~r
}trees[N<<2];
void buid(long long id,long long l,long long r){
	if(l==r){
		trees[id].mid=trees[id].l=trees[id].r=l;
		return;
	}
	int mid=(l+r)>>1;
	buid(id<<1,l,mid);
	buid((id<<1)+1,mid+1,r);
	trees[id].mid=mid;
	trees[id].l=l;
	trees[id].r=r;
}
void updata(int where,long long vul){
	int s=1;
	while(trees[s].l!=trees[s].r){
		
		if(trees[s].mid<where)s<<=1,s++;
		else s<<=1;
	}
	long long k=trees[s].sum;
	s=1;
	while(trees[s].l!=trees[s].r){
		trees[s].sum-=k;
		trees[s].sum+=vul;
		if(trees[s].mid<where)s<<=1,s++;
		else s<<=1;
	}
	trees[s].sum-=k;
	trees[s].sum+=vul;
}
void push_down(int id){
	if(trees[id].l!=trees[id].r){
		trees[id<<1].tag_abb+=trees[id].tag_abb;
		trees[(id<<1)+1].tag_abb+=trees[id].tag_abb;
		trees[id<<1].tag_abb%=       ::r;
		trees[(id<<1)+1].tag_abb%= ::r;
	}
	trees[id].sum+=trees[id].tag_abb%  ::r*(trees[id].r-trees[id].l+1)%  ::r;trees[id].sum%= ::r;
	trees[id].tag_abb=0;
}
long long sum(int l,int r,int id=1){
	push_down(id);
	if(trees[id].l>=l&&trees[id].r<=r)return trees[id].sum%  ::r;
	long long ans=0;
	
	if(trees[id].mid>=l)ans+=sum(l,r,id<<1)%  ::r;
	ans%= ::r;
	if(trees[id].mid+1<=r)ans+=sum(l,r,(id<<1)+1)%  ::r;
	return ans% ::r;
}
void updata_abb(int l,int r,long long vul,int id=1){
	push_down(id);
	
	if(trees[id].l>=l&&trees[id].r<=r){
		trees[id].tag_abb+=vul;
		return;
		
	}trees[id].sum+=(min((long long)r,trees[id].r)-max((long long)l,trees[id].l)+1)% ::r*vul% ::r;
	trees[id].sum%= ::r;
	if(trees[id].mid>=l)updata_abb(l,r,vul,id<<1);
	if(trees[id].mid+1<=r)updata_abb(l,r,vul,(id<<1)+1);
}
void push_up(int id){
	trees[id].sum=trees[id<<1].sum+trees[(id<<1)+1].sum;
}


vector<long long> nexts[1000000];long long fa[1000000],son[1000000],hou_many_son[1000000],top[1000000],dep[1000000],ID[1000000],vuls[1000000];long long kkk=1;
void dfs_init(long long t,long long up_t,long long debug=0){
	fa[t]=up_t;
	hou_many_son[t]=1;long long k=0;
	if(up_t==t)dep[t]=1;
	for(long long i:nexts[t]){
		if(i!=up_t){
			dep[i]=dep[t]+1;
			dfs_init(i,t);
			hou_many_son[t]+=hou_many_son[i];
			if(hou_many_son[i]>k){
				k=hou_many_son[i];
				son[t]=i;
			}
		}
	}
}
void dfs_start_tree(long long t,long long up_t,long long link_head){
	top[t]=link_head;
	//tree_sum.update(kkk,vuls[t]);
	updata(kkk,vuls[t]%  ::r);
	ID[t]=kkk++;
	if(son[t])dfs_start_tree(son[t],t,link_head);
	for(long long i:nexts[t]){
		if(i!=son[t]&&i!=up_t&&i!=t){
			dfs_start_tree(i,t,i);
		}
	}
}
long long LCA_sum(long long x,long long y){
	long long j=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		j+=sum(ID[x],ID[top[x]]);j%=r;
		x=top[x];
		x=fa[x];
	}
	j+=sum((dep[x]<dep[y]?ID[x]:ID[y]),(dep[x]>dep[y]?ID[x]:ID[y]));j%=r;
	return j;
}
void abb_LCA(long long x,long long y,long long up_vul){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		updata_abb(ID[x],ID[top[x]],up_vul%  ::r);
		x=top[x];
		x=fa[x];
	}
	updata_abb((dep[x]<dep[y]?ID[x]:ID[y]),(dep[x]>dep[y]?ID[x]:ID[y]),up_vul%  ::r);
	return ;
}
void som_abb(long long x,long long vul){
	updata_abb(ID[x],ID[x]+hou_many_son[x]-1,vul%  ::r);
}
long long som_sum(long long x){
	return sum(ID[x],ID[x]+hou_many_son[x]-1)%r;
}
int main(){
	ios::sync_with_stdio(0);
	buid(1,1,N);
	cin>>n>>m>>s>>r;
	long long a,b,c,d;
	for(long long i=1;i<=n;i++)cin>>vuls[i];
	for(long long i=0;i<n-1;i++){
		cin>>a>>b;
		nexts[a].push_back(b);
		nexts[b].push_back(a);
	}
	dfs_init(s,s);
	dfs_start_tree(s,0,s); 
	for(long long i=0;i<m;i++){
		cin>>a>>b;
		if(a==1){
			cin>>c>>d;
			abb_LCA(b,c,d);
		}
		if(a==2){
			cin>>c;
			cout<<LCA_sum(b,c)<<'\n';
		}
		if(a==3){
			cin>>c;
			som_abb(b,c);
		}
		if(a==4){
			cout<<som_sum(b)<<'\n';
		}
	}
}

我自己感觉逻辑是没问题的,样例也过了,但就37分,有没有大佬帮我调一下。

2023/12/28 16:41
加载中...