传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3786
写(chao)吐了
等明天写完sone1再发题解
Code:
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int getint(){
int res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}
int n;
struct info{
LL sum;int size;
info(LL _sum=0,int _size=1){sum=_sum;size=_size;}
void clear(){sum=0;size=1;}
void deb(){printf("sum:%d size:%d",(int)sum,size);}
};
struct flag{
LL add;
flag(LL _add=0){add=_add;}
bool empty(){return !add;}
void clear(){add=0;}
};
info operator+(const info &ls,const info &rs){
return info(ls.sum+rs.sum,ls.size+rs.size);
}
info operator+(const info &ls,const flag &rs){
return ls.size?info(ls.sum+(LL)rs.add*ls.size,ls.size):ls;
}
flag operator+(const flag &ls,const flag &rs){
return flag(ls.add+rs.add);
}
struct node{
node *c[4],*f;
flag Cha,All;
info cha,sub,all;
bool rev,inr;
LL val;
node(){
memset(c,0,sizeof c);f=0;
Cha.clear();All.clear();cha.clear();sub.clear();all.clear();
rev=inr=0;val=0;
}
void makerev(){rev^=1;swap(c[0],c[1]);}
void makec(const flag &a){
Cha=Cha+a;cha=cha+a;val=val+a.add;
all=cha+sub;
}
void makes(const flag &a,bool _=1){
All=All+a;all=all+a;sub=sub+a;
if(_)makec(a);
}
void rz(){
cha.clear();sub=info(0,0);all.clear();
if(!inr)cha=all=info(val);
rep(i,0,2)if(c[i])cha=cha+c[i]->cha,sub=sub+c[i]->sub;
rep(i,0,4)if(c[i])all=all+c[i]->all;
rep(i,2,4)if(c[i])sub=sub+c[i]->all;
}
void pd(){
if(rev){
if(c[0])c[0]->makerev();
if(c[1])c[1]->makerev();
rev=0;
}
if(!Cha.empty()){
rep(i,0,2)if(c[i])c[i]->makec(Cha);
Cha.clear();
}
if(!All.empty()){
rep(i,0,4)if(c[i])c[i]->makes(All,i>=2);
All.clear();
}
}
node *C(int i){if(c[i])c[i]->pd();return c[i];}
bool d(int ty){return f->c[ty+1]==this;}
int D(){rep(i,0,4)if(f->c[i]==this)return i;}
void sets(node *x,int d){if(x)x->f=this;c[d]=x;}
bool rt(int ty){
if(ty==0)return !f||(f->c[0]!=this&&f->c[1]!=this);
else return !f||!f->inr||!inr;
}
}nd[maxn*2],*cur=nd+maxn,*pool[maxn],**Cur=pool;
int _cnt;
node *newnode(){
_cnt++;
node *x=(Cur==pool)?cur++:*(--Cur);
rep(i,0,4)x->c[i]=0;x->f=0;
x->all=info(0,0);
x->cha=info(0,0);
x->sub=info(0,0);
x->inr=1;x->rev=0;x->val=0;
return x;
}
int max(long long x,int y){return max(int(x),y);}
void deb(node *x){
if(!x)return;
printf("id:%d f:%d c[0]:%d c[1]:%d c[2]:%d c[3]:%d inr:%d val:%d",
max(x-nd,-1),max(x->f-nd,-1),max(x->c[0]-nd,-1),max(x->c[1]-nd,-1),max(x->c[2]-nd,-1)
,max(x->c[3]-nd,-1),x->inr,int(x->val));
printf(" cha:");x->cha.deb();
printf(" sub:");x->sub.deb();
printf(" all:");x->all.deb();
puts("");
}
void deb(){
for(int i=1;i<=n;i++)deb(nd+i);
for(int i=maxn;i<maxn+_cnt;i++)deb(nd+i);puts("");
}
void dele(node *x){*(Cur++)=x;}
void rot(node *x,int ty){
node *p=x->f;int d=x->d(ty);
if(!p->f)x->f=0;else p->f->sets(x,p->D());
p->sets(x->c[!d+ty],d+ty);x->sets(p,!d+ty);p->rz();
}
void splay(node *x,int ty=0){
while(!x->rt(ty)){
if(x->f->rt(ty))rot(x,ty);
else if(x->d(ty)==x->f->d(ty))rot(x->f,ty),rot(x,ty);
else rot(x,ty),rot(x,ty);
}x->rz();
}
void add(node *u,node *w){
w->pd();
rep(i,2,4)if(!w->c[i]){w->sets(u,i);return;}
node *x=newnode(),*v;
for(v=w;v->c[2]->inr;v=v->C(2));
x->sets(v->c[2],2);x->sets(u,3);
v->sets(x,2);splay(x,2);
}
void del(node *w){
if(w->f->inr){
w->f->f->sets(w->f->c[5-w->D()],w->f->D());
dele(w->f);splay(w->f->f,2);
}else w->f->sets(0,w->D());
w->f=0;
}
void access(node *w){
static node *sta[maxn];
static int top=0;
node *v=w,*u;
for(u=w;u;u=u->f)sta[top++]=u;
while(top)sta[--top]->pd();
splay(w);
if(w->c[1])u=w->c[1],w->c[1]=0,add(u,w),w->rz();
while(w->f){
for(u=w->f;u->inr;u=u->f);
splay(u);
if(u->c[1])w->f->sets(u->c[1],w->D()),splay(w->f,2);
else del(w);
u->sets(w,1);
(w=u)->rz();
}splay(v);
}
void makert(node *x){
access(x);x->makerev();
}
node *findp(node *u){
access(u);u=u->C(0);
while(u&&u->c[1])u=u->C(1);
return u;
}
node *findr(node *u){for(;u->f;u=u->f);return u;}
node* cut(node *u){
node *v=findp(u);
if(v)access(v),del(u),v->rz();
return v;
}
void link(node *u,node *v) {
node* p=cut(u);
if(findr(u)!=findr(v))p=v;
if(p)access(p),add(u,p),p->rz();
}
int main(){
n=getint();
static int fa[maxn];
rep(i,2,n+1)scanf("%d",&fa[i]);
rep(i,1,n+1)scanf("%d",&nd[i].val),nd[i].rz();
rep(i,2,n+1){
makert(nd+fa[i]);
link(nd+i,nd+fa[i]);
}
makert(nd+1);
int m=getint();
while(m--){
makert(nd+1);
char op=getchar();while(!isalpha(op))op=getchar();
if(op=='Q'){
int x=getint();node *v=nd+x;
access(v);
printf("%lld\n",v->cha.sum);
}else
if(op=='C'){
int x=getint(),y=getint();
cut(nd+x);
makert(nd+y);
link(nd+y,nd+x);
makert(nd+1);
}else{
int x=getint();node *v=nd+x;
access(v);
int y=getint();
v->val+=y;
rep(i,2,4)if(v->c[i])
v->c[i]->makes(flag(y));
}
}
return 0;
}