树剖WA 70求助
查看原帖
树剖WA 70求助
227728
冰糖鸽子TJ鸽子协会楼主2021/1/20 12:49

RT,从模板那儿搬过来改的,WA 2,9,10

// Problem: P3178 [HAOI2015]树上操作
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3178
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ll (i*2)
#define rr (i*2+1)
int n,m,r,p=2000000000,U,V,opt,x,y,z,cntp;
int a[M],w[M],d[M],top[M],id[M],fid[M],siz[M],fa[M],son[M];
/*id[i]=j,意为原节点i的id为j,fid则相反*/
vector<int>roadu[M],road[M];
struct node
{
	int s,fl,fr,laz;
}t[M*9];
void push_down(int i)
{
	if(!t[i].laz) return;
	int k=t[i].laz;
	t[ll].s+=(t[ll].fr-t[ll].fl+1)*k;
	t[rr].s+=(t[rr].fr-t[rr].fl+1)*k;
	t[ll].laz+=k;t[rr].laz+=k;
	t[ll].s%=p;t[rr].s%=p;
	t[i].laz=0;
}
void build(int l,int r,int i)
{
	t[i].fl=l;t[i].fr=r;t[i].laz=0;
	if(l==r)
	{
		t[i].s=w[l];
		if(t[i].s>p){t[i].s%=p;}
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,ll);
	build(mid+1,r,rr);
	t[i].s=t[ll].s+t[rr].s;t[i].s%=p;
}
void plused(int l,int r,int x,int y,int i,int k)/*在区间i[x-y]操作,把[l-r]加上k*/
{
	// cout<<x<<' '<<y<<endl;
	if(x>=l&&y<=r)/*l--x--y--r*/
	{
		t[i].laz+=k;
		t[i].s+=(y-x+1)*k;
		return;
	}
	push_down(i);
	int mid=(x+y)/2;
	if(mid>=l)/*[x-mid]是否交[l-r]? */
	{
		plused(l,r,x,mid,ll,k);
	}
	if(mid<r)
	{
		plused(l,r,mid+1,y,rr,k);
	}
	t[i].s=t[ll].s+t[rr].s;t[i].s%=p;
}
int Query(int l,int r,int x,int y,int i)/*在区间i[x-y]操作,求i与[l-r]的交的和*/
{
	int res=0,mid=(x+y)/2;
	if(x>=l&&y<=r)/*l-r包含x-y  l--x--y--t*/
	{
		return t[i].s%p;
	}
	push_down(i);
	if(mid>=l)
	{
		res+=Query(l,r,x,mid,ll);res%=p;
	}
	if(mid<r)
	{
		res+=Query(l,r,mid+1,y,rr);res%=p;
	}
	return res;
}
void dfs1(int x)
{
	if(x==r){d[x]=1;}
	siz[x]=1;
	int sonm=-1;
	for(int i=0;i<road[x].size();i++)
	{
		if(d[road[x][i]]){continue;}
		d[road[x][i]]=d[x]+1;
		dfs1(road[x][i]);
		fa[road[x][i]]=x;
		siz[x]+=siz[road[x][i]];
		if(siz[road[x][i]]>sonm)
		{
			sonm=siz[road[x][i]];
			son[x]=road[x][i];
		}
	}
}
void dfs2(int x,int y)
{
	cntp++;
	w[cntp]=a[x];
	id[x]=cntp;
	fid[cntp]=x;
	top[x]=y;
	if(son[x]==0){return;}
	dfs2(son[x],y);
	for(int i=0;i<road[x].size();i++)
	{
		if(id[road[x][i]]) continue;
		dfs2(road[x][i],road[x][i]);
	}
}
void pLCA()
{
	while(top[x]!=top[y])
	{
		if(d[top[x]]<d[top[y]]) swap(x,y);
		// cout<<x<<' '<<top[x]<<' '<<id[x]<<' '<<id[top[x]]<<endl;
		plused(id[top[x]],id[x],1,n,1,z);
		x=fa[top[x]];
	}
	if(d[x]<d[y]) swap(x,y);//d[x]=3,dy=2
	plused(id[y],id[x],1,n,1,z);
}
void qLCA()/*询问 x,y 两个点的最短路径权值和*/
{
	int res=0;
	while(top[x]!=top[y])
	{
		if(d[top[x]]<d[top[y]]) swap(x,y);
		res+=Query(id[top[x]],id[x],1,n,1)%p;
		res%=p;
		// cout<<res<<endl;
		x=fa[top[x]];
	}
	if(d[x]<d[y]) swap(x,y);//d[x]=3,dy=2
	res+=Query(id[y],id[x],1,n,1)%p;res%=p;
	cout<<res<<endl;
}
void ptree()
{
	plused(id[x],id[x]+siz[x]-1,1,n,1,z);
}
int main()
{
	cin>>n>>m;
	r=1;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<n;i++)
	{
		cin>>U>>V;
		road[U].push_back(V);
		road[V].push_back(U);
	}
	dfs1(r);
	dfs2(r,r);
	// for(int i=1;i<=n;i++)
	// {
		// cout<<top[i]<<' '<<id[i]<<' '<<son[i]<<endl;
	// }
	build(1,n,1);//建xds
	for(int i=1;i<=m;i++)
	{
		cin>>opt;
		if(opt==1)
		{
			cin>>x>>z;y=x;
			pLCA();
		}
		if(opt==2)
		{
			cin>>x>>z;
			ptree();
		}
		if(opt==3)
		{
			cin>>x;y=1;
			qLCA();
		}
	}
	return 0;
}
2021/1/20 12:49
加载中...