20分只过了#1,#3
查看原帖
20分只过了#1,#3
230672
407407lxc楼主2022/8/21 09:55

退役菜鸡Oier(轻喷)、 调废了已经 (看来数据结构不适合我QAQ,CUP,线段树3一生之敌---“抄”题解也调不了))

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2e6+9;
int u[N],v[N],root[N],to[N],cnt;
int id[N],a[N],top[N],size[N],fa[N];
int val[N],son[N],dep[N];
int n,m,R,p,idex;

inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
    return x*f;
}

inline int lson(int x)
{
	return x<<1;
}
inline int rson(int x)
{
	return x<<1|1;
}
struct stu
{
	int sum;
	int lazy;
	int size;
}tree[N*4];

void add_edge(int a,int b)
{
	cnt++;
	u[cnt] = a;
	v[cnt] = b;
	to[cnt] = root[a];
	root[a] = cnt;
	return;
 } 

void update(int x)
{
	tree[x].sum = (tree[lson(x)].sum + tree[rson(x)].sum + p)%p;
	return;
}

void down(int x)
{
	tree[lson(x)].lazy = (tree[lson(x)].lazy+tree[x].lazy+p)%p;
	tree[rson(x)].lazy = (tree[rson(x)].lazy+tree[x].lazy+p)%p;
	tree[lson(x)].sum = (tree[lson(x)].sum+tree[x].lazy*tree[lson(x)].size+p)%p;
	tree[rson(x)].sum = (tree[rson(x)].sum+tree[x].lazy*tree[rson(x)].size+p)%p;
	tree[x].lazy = 0;
	return;
}

int dfs1(int x,int father)
{
	dep[x] = dep[father] + 1;
	fa[x] = father;
	size[x] = 1;
	int maxx = -1;
	for(int i=root[x];i;i=to[i])
	{
		if(v[i] == father) continue;
		size[x] += dfs1(v[i],x);
		if(maxx<size[v[i]])
		{
			maxx = size[v[i]];
			son[x] = v[i];
		}
	}
	return size[x];
}

void dfs2(int x,int topf)
{
	top[x] = topf;
	id[x] = ++idex;
	a[idex] = val[x]%p;
	if(!son[x]) return;
	dfs2(son[x],topf);
	for(int i=root[x];i;i=to[i])
	{
		if(v[i] == son[x] || v[i] == fa[x]) continue;
		dfs2(v[i],v[i]);
	}
	return;
}

void build(int x,int l,int r)
{
	tree[x].size = r-l+1;
	if(l==r)
	{
		tree[x].sum = a[l]%p;
		return;
	}
	int mid = (l+r)>>1;
	build(lson(x),l,mid);
	build(rson(x),mid+1,r);
	update(x);
	return;
}

int sum(int x,int sl,int sr,int l,int r)
{
	if(l<=sl && sr<=r)	return tree[x].sum%p;
	int mid = (sl+sr)>>1;
	int ans = 0;
	down(x);
	if(l<=mid) ans = (ans+sum(lson(x),sl,mid,l,r)+p)%p;
	if(r>mid) ans = (ans+sum(rson(x),mid+1,sr,l,r)+p)%p;
	update(x);
	return ans%p;
}

void add(int x,int sl,int sr,int l,int r,int k)
{
	if(l<=sl && sr<=r)
	{
		tree[x].sum = (tree[x].sum+tree[x].size*k%p + p)%p;
		tree[x].lazy = (tree[x].lazy+k)%p;
		return;
	}
	int mid=(sl+sr)>>1;
	down(x);
	if(l<=mid) add(lson(x),sl,mid,l,r,k);
	if(r>mid) add(rson(x),mid+1,sr,l,r,k);
	update(x);
	return; 
}


int ask_line(int a,int b)
{
	int ans = 0;
	while(top[a]!=top[b])
	{
		if(dep[a]<dep[b]) swap(a,b);
		ans = (ans + sum(1,1,n,id[top[a]],id[a])%p)%p;
		a = fa[top[a]]; 
	}
	if(dep[a]<dep[b]) swap(a,b);
	ans = (ans + sum(1,1,n,id[b],id[a])%p)%p;
	return ans%p;
}

void add_line(int a,int b,int k)
{
	while(top[a]!=top[b])
	{
		if(dep[a]<dep[b]) swap(a,b);
		add(1,1,n,id[top[a]],id[a],k);
		a = fa[top[a]];
	}
	if(dep[a]<dep[b]) swap(a,b);
	add(1,1,n,id[b],id[a],k);
	return;
}

int ask_tree(int x)
{
	return sum(1,1,n,id[x],id[x]+size[x]-1)%p;
}

void add_tree(int x,int k)
{
	add(1,1,n,id[x],id[x]+size[x]-1,k);
	return;
}

int main()
{
	scanf("%d%d%d%d",&n,&m,&R,&p);
	for(int i=1;i<=n;i++) val[i]=read();
	for(int i=1;i<=n-1;i++)
	{
		int a,b;
		a=read();b=read();
		add_edge(a,b);
		add_edge(b,a);
	}
	dfs1(R,R);
	dfs2(R,R); 
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int rep,a,b,c;
		rep = read(); 
		if(rep == 1)
		{
			a=read();b=read();c=read();
			c%=p;
			add_line(a,b,c);
		}
		if(rep == 2)
		{
			a=read();b=read();
			printf("%d\n",ask_line(a,b)%p);
		}
		if(rep == 3)
		{
			a=read();b=read();
			b%=p;
			add_tree(a,b);
		}
		if(rep == 4)
		{
			a=read();
			printf("%d\n",ask_tree(a)%p);
		}	
	}
	return 0;
 } 
2022/8/21 09:55
加载中...