省选模拟21

超级难的字符串,物理题,能过得只有最后一个题

虽然是这样,但是收获依旧很大!!

T3 祖先

根号分治,均摊复杂度的利器

对于度数大于根号的,我们边更改边维护答案

小于根号的,我们就直接统计

AC_code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
	int s=0,t=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s*t;
}
const int N=2e5+5;
const int SQ=455;
const ull mod=1ull<<63;
int n,Q;ull w[N];
struct E{int to,nxt;}e[N];
int head[N],rp,du[N];
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
int big[N],bys[N],cb,sq;bool isb[N];
int blo[N][SQ];
void dfs_bl(int x,int r,int bg){
	blo[x][bg]=r;
	for(int i=head[x];i;i=e[i].nxt)
		dfs_bl(e[i].to,r,bg);
}
int dfn[N],cnt,dfm[N],siz[N];
ull sm2[N],sz2[N],smz[N];
void dfs_al(int x){
	dfn[x]=++cnt;siz[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		dfs_al(y);siz[x]+=siz[y];
	}dfm[x]=cnt;
}
struct BIT{
	ull tr1[N],tr2[N];
	void insert(int x,ull v){
		for(int i=x;i<=n;i+=(i&-i)){
			tr1[i]+=v;tr2[i]+=1ull*v*(x-1);
		}
	}
	void ins(int l,int r,ull v){
		insert(l,v);insert(r+1,-v);
	}
	ull query(int x){
		ull ret=0;
		for(int i=x;i;i-=(i&-i))ret+=1ull*x*tr1[i]-tr2[i];
		return ret;
	}
	ull qry(int l,int r){
		return query(r)-query(l-1);
	}
}bit;
signed main(){
	freopen("ancestor.in","r",stdin);
	freopen("ancestor.out","w",stdout);
	n=read();Q=read();sq=sqrt(n);
	fo(i,2,n){
		int x=read();
		add_edg(x,i);
		du[x]++;
	}
	fo(i,1,n)w[i]=read();
	fo(x,1,n)if(du[x]>sq){
		isb[x]=true;big[++cb]=x;bys[x]=cb;
		for(int i=head[x];i;i=e[i].nxt)dfs_bl(e[i].to,e[i].to,cb);
	}dfs_al(1);
	fo(i,1,n)bit.ins(dfn[i],dfn[i],w[i]);
	fo(c,1,cb){
		int x=big[c];
		for(int i=head[x];i;i=e[i].nxt){
			int y=e[i].to;ull ret=bit.qry(dfn[y],dfm[y]);
			sz2[x]+=siz[y]*siz[y];
			sm2[x]+=ret*ret;
			smz[x]+=ret*siz[y];
		}
	}
	while(Q--){
		char tp[10];scanf("%s",tp+1);
		int u;ull d;
		if(tp[1]=='S'){
			u=read();d=read();
			fo(c,1,cb)if(blo[u][c]){
				int v=blo[u][c];ull sum=bit.qry(dfn[v],dfm[v]);
				sm2[big[c]]+=2*sum*d+d*d;
				smz[big[c]]+=d*siz[v];
			}
			bit.ins(dfn[u],dfn[u],d);
			//cerr<<bit.qry(dfn[u],dfn[u])<<endl;
		}
		if(tp[1]=='M'){
			u=read();d=read();
			fo(c,1,cb){
				if(blo[u][c]){
					int v=blo[u][c];ull sum=bit.qry(dfn[v],dfm[v]);
					sm2[big[c]]+=2*sum*d*siz[u]+d*d*siz[u]*siz[u];
					smz[big[c]]+=d*siz[u]*siz[v];
				}
				if(dfn[big[c]]>=dfn[u]&&dfn[big[c]]<=dfm[u]){
					sm2[big[c]]+=2*smz[big[c]]*d+sz2[big[c]]*d*d;
					smz[big[c]]+=sz2[big[c]]*d;
				}
			}
			bit.ins(dfn[u],dfm[u],d);
			//cerr<<bit.qry(dfn[u],dfn[u])<<endl;
		}
		if(tp[1]=='Q'){
			u=read();ull ans=0;
			if(!isb[u]){
				for(int i=head[u];i;i=e[i].nxt){
					int y=e[i].to;
					ull tmp=bit.qry(dfn[y],dfm[y]);
					ans-=tmp*tmp;
				}
				ull tmp=bit.qry(dfn[u],dfm[u]);
				ans+=tmp*tmp;
				tmp=bit.qry(dfn[u],dfn[u]);
				ans-=tmp*tmp;
			}
			else {
				ull tmp=bit.qry(dfn[u],dfm[u]);
				ans=tmp*tmp-sm2[u];
				tmp=bit.qry(dfn[u],dfn[u]);
				ans-=tmp*tmp;
			}
			printf("%llu\n",ans/2%mod);
		}
	}
}
posted @ 2022-03-04 14:58  fengwu2005  阅读(42)  评论(0编辑  收藏  举报