样例都过不去~求大佬差错
查看原帖
样例都过不去~求大佬差错
55650
flowerletter楼主2018/12/17 20:49
#include <bits/stdc++.h>
using namespace std;
#define lson root<<1
#define rson root<<1|1
const int MAXN = (2e6)+10;
struct Edge
{
	int to,next;
}e[MAXN<<1];
struct Segment_Tree
{
	int sum,lazy,size;
}tree[MAXN<<2];
int n,q,Root,Mod,cnt,dfs_time;
int head[MAXN],deep[MAXN],top[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN];
int a[MAXN],b[MAXN];
inline int read()
{
	int x=0,f=1;char c=getchar();
	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 void add(int u,int v)
{
	cnt++;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
inline void push_up(int root)
{
    tree[root].sum=tree[lson].sum+tree[rson].sum;
    tree[root].sum%=Mod;
}
inline void push_down(int root)
{
	tree[lson].lazy+=tree[root].lazy;
	tree[rson].lazy+=tree[root].lazy;
	tree[lson].sum+=tree[lson].size*tree[root].lazy;
	tree[lson].sum%=Mod;
	tree[rson].sum+=tree[rson].size*tree[root].lazy;
	tree[rson].sum%=Mod;
	tree[root].lazy=0;
}
void dfs1(int now,int father,int dep)
{
	deep[now]=dep;
	fa[now]=father;
	size[now]=1;
	for(int i=head[now];i;i=e[i].next){
		if(e[i].to==father) continue;
		dfs1(e[i].to,now,dep+1);
		if(size[e[i].to]>size[son[now]]) son[now]=e[i].to;
		size[now]+=size[e[i].to];
	}
}
void dfs2(int now,int topfather)
{
	id[now]=++dfs_time;
	a[cnt]=b[now];
	top[now]=topfather;
	if(!son[now]) return ;
	dfs2(son[now],topfather);
	for(int i=head[now];i;i=e[i].next){
		if(fa[now]==e[i].to || e[i].to==son[now]) continue;
		dfs2(e[i].to,e[i].to);
	}
}
inline void build(const int root,const int l,const int r)
{
	tree[root].size=r-l+1;
	if(l==r){
		tree[root].sum=a[l];
		return ;
	}
	const int mid=l+r>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	push_up(root);
}
inline void update(const int root,const int l,const int r,const int L,const int R,const int k)
{
	if(l>=L && r<=R){
		tree[root].sum+=tree[root].size*k;
		tree[root].sum%=Mod;
		tree[root].lazy+=k;
		return ;
	}
	if(tree[root].lazy) push_down(root);
	const int mid=l+r>>1;
	if(R<=mid) update(lson,l,mid,L,R,k);
	else if(L>mid) update(rson,mid+1,r,L,R,k);
	else update(lson,l,mid,L,R,k),update(rson,mid+1,r,L,R,k);
	push_up(root);
	
}
inline int query(const int root,const int l,const int r,const int L,const int R)
{
	if(l>=L && r<=R) return tree[root].sum;
	if(tree[root].lazy) push_down(root);
	const int mid=l+r>>1;
	if(R<=mid) return query(lson,l,mid,L,R);
	else if(L>mid) return query(rson,mid+1,r,L,R);
	else return (query(lson,l,mid,L,R)+query(rson,mid+1,r,L,R))%Mod;
	push_up(root);
}
inline void Tree_update_edge(int x,int y,int k)
{
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	update(1,1,n,id[x],id[y],k);
}
inline int Tree_query_edge(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans+=query(1,1,n,id[top[x]],id[x]);
		ans%=Mod;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	return (ans+query(1,1,n,id[x],id[y]))%Mod;
}
inline void Init()
{
	dfs1(Root,0,1);
	dfs2(Root,Root);
	build(1,1,n);
}
inline void work1()
{
	int x=read(),y=read(),z=read();
	Tree_update_edge(x,y,z);
}
inline void work2()
{
	int x=read(),y=read();
	printf("%d\n",Tree_query_edge(x,y));
}
inline void work3()
{
	int x=read(),z=read();
	update(1,1,n,id[x],id[x]+size[x]-1,z);
}
inline void work4()
{
	int x=read();
	printf("%d\n",query(1,1,n,id[x],id[x]+size[x]-1));
}
int main()
{
	n=read(),q=read(),Root=read(),Mod=read();
	for(int i=1;i<=n;i++) b[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	Init();
	while(q--){
	    int op=read();
		if(op==1) work1();
		if(op==2) work2();
		if(op==3) work3();
		if(op==4) work4();	
	}
	return 0;
}
2018/12/17 20:49
加载中...