对于树链剖分,线段树怎么动态开点???(样例过不了,动态开点建树炸了)
查看原帖
对于树链剖分,线段树怎么动态开点???(样例过不了,动态开点建树炸了)
141335
qwq2519楼主2020/10/12 10:29
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i(j);i!=(k+1);++i)
using namespace std;
typedef long long ll;
const int AN=1e6;

inline void read(int &x) {
	x=0;
	register char ch=getchar();
	int w=0;
	while(ch>'9'||ch<'0') {
		w|=ch=='-';
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-48;
		ch=getchar();
	}
	w?x=~(x-1):x;
}

int N,M,P;
int b[AN],a[AN];
int size[AN],son[AN],dfn[AN],num,dep[AN],fa[AN];
int top[AN];
struct graph {
	int head[AN],next[AN],tot,ver[AN];
	inline void add(int a,int b) {
		ver[++tot]=b;
		next[tot]=head[a];
		head[a]=tot;
	}
} G;

struct Segmentree {
	int lc[AN<<1],rc[AN<<1],cnt,sum[AN<<1],root,lazy[AN<<1];
//	Segmentree() {
//		memset(lazy,0xff,sizeof lazy);
//		root=cnt=0;
//	}
//	inline void spread(int p,int L,int R) {
////		if(lazy[p]==-1) return;
//        if(lazy[p]==0) return ;
//		int mid=(L+R)>>1;
//		if(lc[p]) {
//			lazy[lc[p]]=lazy[p];
//			sum[lc[p]]+=((mid-L+1)*lazy[p])%P;
//		}
//		if(rc[p]) {
//			lazy[rc[p]]=lazy[p];
//			sum[rc[p]]+=((R-mid)*lazy[p])%P;
//		}
//		lazy[p]=0;
////		lazy[p]=-1;
//	}

	inline void spread(int p,int L,int R) {
		if(!lazy[p]) return ;
		if(!lc[p]) lc[p]=++cnt;
		if(!rc[p]) rc[p]=++cnt;
		int mid=(L+R)>>1;

		sum[lc[p]]+=(mid-L+1)*lazy[p];
		sum[rc[p]]+=(R-mid)*lazy[p];

		lazy[rc[p]]+=lazy[p];
		lazy[lc[p]]+=lazy[p];
		lazy[p]=0;
	}

	inline void insert(int &p,int L,int R,int ll,int rr,int v) {
		if(!p) p=++cnt;
		spread(p,L,R);
		if(ll<=L&&rr>=R) {
			sum[p]+=((R-L+1)*v)%P;
			lazy[p]+=v;
			return;
		}
		int mid=(L+R)>>1;
		if(ll<=mid)insert(lc[p],L,mid,ll,rr,v);
		if(rr>mid) insert(rc[p],mid+1,R,ll,rr,v);
		sum[p]=(sum[lc[p]]+sum[rc[p]])%P;
	}
	inline int query(int p,int L,int R,int ll,int rr) {
		if(!p) return 0;
		spread(p,L,R);
		if(ll<=L&&rr>=R) {
			return sum[p];
		}
		int mid=(L+R)>>1;
		int val(0);
		if(ll<=mid) val+=query(lc[p],L,mid,ll,rr)%P;
		if(rr>mid) val+=query(rc[p],mid+1,R,ll,rr)%P;
		return val%P;
	}
} S;

inline int dfs1(int x,int fath) {
	dep[x]=dep[fath]+1;
	fa[x]=fath;
	size[x]=1;
	int maxson=-1;
	for(register int i(G.head[x]); i; i=G.next[i]) {
		int y=G.ver[i];
		if(y==fath) continue;
		dfs1(y,x);
		size[x]+=size[y];
		if(size[y]>maxson) maxson=size[y],son[x]=y;
	}
}
inline void dfs2(int x,int topf) {
	dfn[x]=++num;
	a[num]=b[x];
	top[x]=topf;
	if(!son[x]) return;
	dfs2(son[x],topf);
	for(register int i(G.head[x]); i; i=G.next[i]) {
		int y=G.ver[i];
		if(dfn[y])	 continue;
		dfs2(y,y);
	}
}

inline int querychain(int x,int y) {
	int sum(0);
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		sum=(sum+S.query(S.root,1,N,dfn[top[x]],dfn[x]) )%P;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	sum=(sum+S.query(S.root,1,N,dfn[x],dfn[y]))%P;
	return sum;
}

inline void changechain(int x,int y,int k) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		S.insert(S.root,1,N,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	S.insert(S.root,1,N,dfn[x],dfn[y],k);
}


int main() {
	int R;
	read(N);
	read(M);
	read(R);
	read(P);
	rep(i,1,N) read(b[i]);
	rep(i,1,N-1) {
		int x,y;
		read(x);
		read(y);
		G.add(x,y);
		G.add(y,x);
	}
	dfs1(R,0);
	dfs2(R,R);
	cout<<"----"<<endl;
	rep(i,1,N) cout<<dfn[i]<<' '<<a[dfn[i]]<<endl;
	
	
	rep(i,1,N) S.insert(S.root,1,N,dfn[i],dfn[i],a[dfn[i]]);
	cout<<S.sum[1]<<endl;
//	cout<<dfn[R]<<' '<<size[R]<<endl;
//	cout<<S.query(S.root,1,N,1,dfn[2]+size[2]-1);
//	rep(i,1,N) cout<<S.query(S.root,1,N,dfn[i],dfn[i]+size[i]-1)<<' ';
//	rep(i,1,N) cout<<size[i]<<'\n';
//    rep(i,1,N) cout<<dfn[i]<<'\n';
//    rep(i,1,N) cout<<a[i]<<'\n';
//    rep(i,1,N) cout<<dep[i]<<'\n';
//	int op,x,y,z;
//	while(M--) {
//		read(op);
//		if(op==1) {
//			read(x);
//			read(y);
//			read(z);
//			changechain(x,y,z%P);
//		} else if(op==2) {
//			read(x);
//			read(y);
//			cout<<querychain(x,y)%P<<'\n';
//		} else if(op==3) {
//			read(x);
//			read(z);
//			S.insert(S.root,1,N,dfn[x],dfn[x]+size[x]-1,z%P);
//		} else if(op==4) {
//			read(x);
//			cout<<S.query(S.root,1,N,dfn[x],dfn[x]+size[x]-1)<<'\n';
//		}
//	}
	return 0;
}
/*
5 5 2 24
7 3 7 8 0
1 2
1 5
3 1
4 1
3 4 2
3 2 2
4 5
1 5 1 3
2 1 3
*/

初始化查询整棵树的和就错了,,输出1。。。。

2020/10/12 10:29
加载中...