省选模拟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);
}
}
}
QQ:2953174821