重剖板子 WA 19pts 求调,玄关
查看原帖
重剖板子 WA 19pts 求调,玄关
542128
liyixin0514楼主2024/11/25 21:51

rt,萌新刚学重剖 1ms,WA 求条。提前拜谢大佬 orz.

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace tree_pou_heavy {
	constexpr int N=1e5+7;
	int n,m,rt,p;
	int add(int a,int b) { return a+b>=p ? a+b-p : a+b; }
	void _add(int &a,int b) { a=add(a,b); }
	void _max(int &a,int b) { a=max(a,b); }
	int a[N];
	int u,v;
	struct edge {
		int to,ne;
	}e[N<<1];
	int head[N],e_cnt;
	void addedge(int u,int v) { e[++e_cnt] = {v, head[u]}; head[u]=e_cnt; }
	struct tree {
		int fa[N],dep[N],siz[N],gson[N];
		int st[30][N];
		int lcamin(int u,int v) { return dfn[u]<dfn[v] ? u : v; }
		int getlca(int u,int v) {
			if(u==v) return u;
			int mn=min(dfn[u],dfn[v])+1, mx=max(dfn[u],dfn[v]);
			int lg=__lg(mx-mn+1);
			return lcamin(st[lg][mn],st[lg][mx-(1<<lg)+1]);
		}
		int dfn[N],eddfn[N],cnt,idfn[N];
		int top[N];
		void dfs(int u,int f) {
			fa[u]=f;
			siz[u]=1;
			for(int i=head[u]; i; i=e[i].ne) {
				int v=e[i].to;
				if(v==f) continue;
				dfs(v,u);
				siz[u]+=siz[v];
				if(siz[v]>siz[gson[u]]) gson[u]=v;
			}
		}
		void dfs(int u) {
			dfn[u]=eddfn[u]=++cnt;
			idfn[cnt]=u;
			st[0][cnt]=fa[u];
			if(gson[u]) top[gson[u]]=top[u], dfs(gson[u]);
			_max(eddfn[u],eddfn[gson[u]]);
			for(int i=head[u]; i; i=e[i].ne) {
				int v=e[i].to;
				if(v==fa[u] || v==gson[u]) continue;
				top[v]=v, dfs(v);
				_max(eddfn[u],eddfn[v]);
				if(siz[v]>siz[gson[u]]) gson[u]=v;
			}
		}
		int tr[N<<2],tag[N<<2];
		int p;
		void build() {
			p=1;
			while(p-2<n) p<<=1;
			rep(i,1,n) tr[p+i]=a[idfn[i]];
			per(i,p-1,1) tr[i]=add(tr[i<<1],tr[i<<1|1]);
		}
		void init() {
			dfs(rt,0);
			// pf("gson "); rep(i,1,n) pf("%d ",gson[i]); pf("\n");
			top[rt]=rt;
			dfs(rt);
			// pf("dfn "); rep(i,1,n) pf("%d ",dfn[i]); pf("\n");
			// pf("eddfn "); rep(i,1,n) pf("%d ",eddfn[i]); pf("\n");
			// pf("top "); rep(i,1,n) pf("%d ",top[i]); pf("\n");
			int lg=__lg(n);
			rep(k,1,lg) for(int i=1;i+(1<<k)-1<=n;i++) st[k][i]=lcamin(st[k-1][i],st[k-1][i+(1<<(k-1))]);
			build();
		}
		void maketag(int u,int x,int siz) { _add(tr[u],1ll*x*siz%p), _add(tag[u],x); }
		void pushup(int u,int siz) { tr[u]=add(add(tr[u<<1],tr[u<<1|1]),1ll*siz*tag[u]); }
		void _update(int l,int r,int x) {
			l=p+l-1, r=p+r+1;
			int siz=1;
			while(l^r^1) {
				if((l&1)^1) maketag(l^1,x,siz);
				if(r&1) maketag(r^1,x,siz);
				l>>=1, r>>=1, siz<<=1;
				pushup(l,siz), pushup(r,siz);
			} 
			for(l>>=1, siz<<=1; l; l>>=1, siz<<=1) pushup(l,siz);
		}
		int _query(int l,int r) {
			l=p+l-1, r=p+r+1;
			int sizl=0,sizr=0,siz=1;
			int s=0;
			while(l^r^1) {
				if((l&1)^1) _add(s,tr[l^1]), sizl+=siz;
				if(r&1) _add(s,tr[r^1]), sizr+=siz;
				l>>=1, r>>=1, siz<<=1;
				_add(s,1ll*tag[l]*sizl%p), _add(s,1ll*tag[r]*sizr%p);
			}
			for(l>>=1, sizl+=sizr; l; l>>=1) _add(s,1ll*tag[l]*sizl%p);
			return s;
		}
		void update(int u,int v,int x) {
			int lca=getlca(u,v);
			// pf("%d %d %d\n",u,v,lca);
			while(dfn[top[u]]>dfn[lca]) _update(dfn[top[u]],dfn[u],x), u=fa[top[u]];
			_update(dfn[lca],dfn[u],x);
			while(dfn[top[v]]>dfn[lca]) _update(dfn[top[v]],dfn[v],x), v=fa[top[v]];
			if(dfn[v]>=dfn[lca]+1) _update(dfn[lca]+1,dfn[v],x);
		}
		void update(int u,int x) {
			_update(dfn[u],eddfn[u],x);
		}
		int query(int u,int v) {
			int lca=getlca(u,v);
			int s=0;
			while(dfn[top[u]]>dfn[lca]) _add(s,_query(dfn[top[u]],dfn[u])), u=fa[top[u]];
			_add(s,_query(dfn[lca],dfn[u]));
 			while(dfn[top[v]]>dfn[lca]) _add(s,_query(dfn[top[v]],dfn[v])), v=fa[top[v]];
			if(dfn[v]>=dfn[lca]+1) _add(s,_query(dfn[lca]+1,dfn[v]));
			return s;
		}
		int query(int u) {
			return _query(dfn[u],eddfn[u]);
		}
		// void write() {
			// pf("tr "); rep(i,1,p+n) pf("%d ",tr[i]); pf("\n");
			// pf("tag "); rep(i,1,p+n) pf("%d ",tag[i]); pf("\n");
		// }
	}T;
	int op,x;
	void main() {
		sf("%d%d%d%d",&n,&m,&rt,&p);
		rep(i,1,n) sf("%d",&a[i]), a[i]%=p;
		rep(i,1,n-1) sf("%d%d",&u,&v), addedge(u,v), addedge(v,u);
		T.init();
		// T.write();
		rep(i,1,m) {
			sf("%d",&op);
			if(op==1) sf("%d%d%d",&u,&v,&x), T.update(u,v,x);
			else if(op==2) sf("%d%d",&u,&v), pf("%d\n",T.query(u,v));
			else if(op==3) sf("%d%d",&u,&x), T.update(u,x);
			else sf("%d",&u), pf("%d\n",T.query(u));
			// T.write();
		}
	}
}
int main() {
	#ifdef LOCAL
	freopen("in.txt","r",stdin);
	freopen("my.out","w",stdout);
	#endif
	tree_pou_heavy :: main();
}
2024/11/25 21:51
加载中...