(玄关)求调WA+RE19pts(P3384 【模板】重链剖分/树链剖分)
  • 板块题目总版
  • 楼主hdbhdbhdb
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/15 18:51
  • 上次更新2024/10/15 20:50:12
查看原帖
(玄关)求调WA+RE19pts(P3384 【模板】重链剖分/树链剖分)
550325
hdbhdbhdb楼主2024/10/15 18:51

操作2会出错,求调

#include<bits/stdc++.h>
using namespace std;
struct init{
	int f,hs,dep,num,val;
	vector<int> s;
}t[100001];
struct intt{
	int l,r,num,lazy;
}tree[300001];
int n,m,r,p,top[100001],cnt=1,id[100001],iv[100001];
void in_t(int i,int l,int r){
	tree[i].lazy=0;
	tree[i].l=l;
	tree[i].r=r;
	if(l==r){
		tree[i].num=t[iv[l]].val;
		return;
	}
	int mid=(l+r)>>1;
	in_t(i*2,l,mid);
	in_t(i*2+1,mid+1,r);
	tree[i].num=tree[i*2].num+tree[i*2+1].num;
}
void dfs1(int x,int d,int f){
	t[x].dep=d;
	t[x].f=f;
	int maxnum=-1;
	for(int i=0;i<t[x].s.size();i++){
		if(t[x].s[i]==f) continue;
		dfs1(t[x].s[i],d+1,x);
		t[x].num+=t[t[x].s[i]].num;
		if(t[t[x].s[i]].num>maxnum) t[x].hs=t[x].s[i],maxnum=t[t[x].s[i]].num;
	}
}
void dfs2(int x,int topt){
	top[x]=topt;
	id[x]=cnt;
	cout<<x<<" "<<id[x]<<endl;
	iv[cnt]=x;
	cnt++;
	if(t[x].num==1) return;
	dfs2(t[x].hs,topt);
	for(int i=0;i<t[x].s.size();i++){
		if(t[x].s[i]==t[x].f||t[x].s[i]==t[x].hs) continue;
		dfs2(t[x].s[i],t[x].s[i]);
	}
}
int act(int i,int l,int r){
	if(l==tree[i].l&&r==tree[i].r) return tree[i].num+tree[i].lazy*(r-l+1);
	int mid=(tree[i].l+tree[i].r)>>1;
	if(mid<l) return act(i*2+1,l,r)+tree[i].lazy*(r-l+1);
	if(mid>=r) return act(i*2,l,r)+tree[i].lazy*(r-l+1);
	return act(i*2,l,mid)+act(i*2+1,mid+1,r)+tree[i].lazy*(r-l+1);
}
int solve2(int u,int v,int ans){
	ans%=p;
	while(top[u]!=top[v]){
		if(t[top[u]].dep<t[top[v]].dep){
			int uv;
			uv=u;u=v;v=uv;
		}
		ans+=act(1,id[top[u]],id[u]);
		ans%=p;
		u=top[u];
		u=t[u].f;
	}
	if(t[u].dep<t[v].dep){
		int uv;
		uv=u;u=v;v=uv;
	}
	return (ans+act(1,min(id[u],id[v]),max(id[u],id[v])))%p;
}
void q(int i,int l,int r,int ans){
//	cout<<i<<" "<<l<<" "<<r<<" "<<tree[i].l<<" "<<tree[i].r<<" "<<ans<<endl;
	if(l==tree[i].l&&r==tree[i].r){tree[i].lazy+=ans;return;}
	int mid=(tree[i].l+tree[i].r)>>1;
	if(mid<l){q(i*2+1,l,r,ans);return;} 
	if(mid>=r){q(i*2,l,r,ans);return;} 
	q(i*2,l,mid,ans);
	q(i*2+1,mid+1,r,ans);
}
int solve1(int u,int v,int ans){
	ans%=p;
	while(top[u]!=top[v]){
		if(t[top[u]].dep<t[top[v]].dep){
			int uv;
			uv=u;u=v;v=uv;
		}
		q(1,id[top[u]],id[u],ans);
		u=top[u];
		u=t[u].f;
	}
	if(t[u].dep<t[v].dep){
		int uv;
		uv=u;u=v;v=uv;
	}
	q(1,min(id[u],id[v]),max(id[u],id[v]),ans);
}
void solve3(int x,int ans){
	q(1,id[x],id[x]+t[x].num-1,ans);
}
int solve4(int x){
	return act(1,id[x],id[x]+t[x].num-1)%p;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&r,&p);
	int x,y,z;
	for(int i=1;i<=n;i++){
		scanf("%d",&t[i].val);
		t[i].num=1;
		t[i].hs=i;
	}
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		t[x].s.push_back(y);
		t[y].s.push_back(x);
	}
	dfs1(r,1,r);
	dfs2(r,r);
	in_t(1,1,n);
	int solve;
	for(int i=1;i<=m;i++){
		cin>>solve;
		if(solve==1) scanf("%d%d%d",&x,&y,&z),solve1(x,y,z);
		if(solve==2) scanf("%d%d",&x,&y),printf("%d\n",solve2(x,y,0));
		if(solve==3) scanf("%d%d",&x,&z),solve3(x,z);
		if(solve==4) scanf("%d",&x),printf("%d\n",solve4(x));
	}
	return 0;
}
/*
8 10 2 448348
458 718 447 857 633 264 238 944
1 2
2 3
3 4
6 2
1 5
5 7
8 6
3 7 611
4 6
3 1 267
3 2 111
1 6 1 153
3 7 673
4 8
2 6 1
4 7
3 4 228
*/
2024/10/15 18:51
加载中...