省選模擬21
阿新 • • 發佈:2022-03-04
超級難的字串,物理題,能過得只有最後一個題
雖然是這樣,但是收穫依舊很大!!
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); } } }