树剖板子RE73pts求调
查看原帖
树剖板子RE73pts求调
934924
nr0628楼主2023/7/28 11:46

空间都开 2×1052\times10^5 还是 RE。

(Segmentation fault with invalid memory reference\texttt{Segmentation fault with invalid memory reference})

代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
#define re register
#define brk break
#define rtn return
#define nxtper next_permutation
#define preper prev_permutation
#define eb emplace_back
#define pb eb
#define ins insert
#define rep(i,a,b) for(re int i(a);i<=b;++i)
#define req(i,a,b) for(re int i(a);i>=b;--i)
#define readf(s) freopen(s,"r",stdin)
#define writef(s) freopen(s,"w",stdout)
inline int read()
{
    re int x=0; re bool f=1; re char ch=getchar();
    while(!isdigit(ch)) f=ch=='-'?0:f,ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?x:-x;
}
inline void write(int x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+48);
}
int n,m,rt,mod,head[400001],nxt[400001],to[400001],cnt;
void add_undirected_edge(int x,int y)
{
	nxt[++cnt]=head[x];
	to[cnt]=y;
	head[x]=cnt;
	nxt[++cnt]=head[y];
	to[cnt]=x;
	head[y]=cnt;
}
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
int w[200001],wew[200001];
namespace segtree
{
	int tree[200001],tag[200001];
	void add_tag(int p,int pl,int pr,int d)
	{
		tag[p]+=d;
		(tree[p]+=d*(pr-pl+1))%=mod;
	}
	void pushup(int p)
	{
		(tree[p]=tree[ls(p)]+tree[rs(p)])%=mod;
	}
	void pushdown(int p,int pl,int pr)
	{
		if(tag[p])
		{
			int mid=pl+pr>>1;
			add_tag(ls(p),pl,mid,tag[p]);
			add_tag(rs(p),mid+1,pr,tag[p]);
			tag[p]=0;
		}
	}
	void build(int p,int pl,int pr)
	{
		tag[p]=0;
		if(pl==pr){(tree[p]=wew[pl])%=mod; rtn;}
		int mid=pl+pr>>1;
		build(ls(p),pl,mid);
		build(rs(p),mid+1,pr);
		pushup(p);
	}
	void update(int l,int r,int p,int pl,int pr,int d)
	{
		if(l<=pl&&pr<=r)
		{
			add_tag(p,pl,pr,d);
			rtn;
		}
		pushdown(p,pl,pr);
		int mid=pl+pr>>1;
		if(l<=mid) update(l,r,ls(p),pl,mid,d);
		if(r>mid) update(l,r,rs(p),mid+1,pr,d);
		pushup(p);
	}
	int query(int l,int r,int p,int pl,int pr)
	{
		if(pl>=l&&r>=pr) return tree[p]%=mod;
		pushdown(p,pl,pr);
		int mid=pl+pr>>1,ans=0;
		if(l<=mid) (ans+=query(l,r,ls(p),pl,mid))%=mod;
		if(r>mid) (ans+=query(l,r,rs(p),mid+1,pr))%=mod;
		return ans%=mod;
	}
}
namespace dividedtree
{
	int num,father[200001],son[200001],depth[200001],siz[200001],top[200001],id[200001];
	void dfs1(int x,int fa)
	{
		depth[x]=depth[fa]+1;
		father[x]=fa;
		siz[x]=1;
		for(int i=head[x];i;i=nxt[i])
			if(to[i]!=fa)
			{
				father[to[i]]=x;
				dfs1(to[i],x);
				siz[x]+=siz[to[i]];
				if(!son[x]||siz[son[x]]<siz[to[i]]) son[x]=to[i];
			}
	}
	void dfs2(int x,int tx)
	{
		id[x]=++num;
		wew[num]=w[x];
		top[x]=tx;
		if(!son[x]) rtn;
		dfs2(son[x],tx);
		for(int i=head[x];i;i=nxt[i])
			if(to[i]!=father[x]&&to[i]!=son[x]) dfs2(to[i],to[i]); 
	}
	void update1(int x,int y,int z)
	{
		while(top[x]!=top[y])
		{
			if(depth[top[x]]<depth[top[y]]) swap(x,y);
			segtree::update(id[top[x]],id[x],1,1,n,z);
			x=father[top[x]];
		}
		if(depth[x]>depth[y]) swap(x,y);
		segtree::update(id[x],id[y],1,1,n,z);
	}
	int query1(int x,int y)
	{
		int ans=0;
		while(top[x]!=top[y])
		{
			if(depth[top[x]]<depth[top[y]]) swap(x,y);
			(ans+=segtree::query(id[top[x]],id[x],1,1,n))%=mod;
			x=father[top[x]];
		}
		if(depth[x]>depth[y]) swap(x,y);
		(ans+=segtree::query(id[x],id[y],1,1,n))%=mod;
		return ans;
	}
	void update2(int x,int k)
	{
		segtree::update(id[x],id[x]+siz[x]-1,1,1,n,k);
	}
	int query2(int x)
	{
		return segtree::query(id[x],id[x]+siz[x]-1,1,1,n)%mod;
	}
}
signed main()
{
	cin>>n>>m>>rt>>mod;
	rep(i,1,n)cin>>w[i];
	rep(i,1,n-1) add_undirected_edge(read(),read());
	dividedtree::dfs1(rt,0);dividedtree::dfs2(rt,rt);
	segtree::build(1,1,n);
	int opt,x,y,z;
	rep(i,1,m)
	{
		cin>>opt>>x;
		switch(opt)
		{
			case 1:cin>>y>>z;dividedtree::update1(x,y,z);brk;
			case 2:cin>>y;cout<<dividedtree::query1(x,y)<<"\n";brk;
			case 3:cin>>y;dividedtree::update2(x,y);brk;
			case 4:cout<<dividedtree::query2(x)<<"\n";brk;
		}
	}
	return 0;
}
2023/7/28 11:46
加载中...