树链剖分,徒手玩操作
很直接很裸的做就可以了,写了1h然后我觉得肯定要调很久的时候,直接过样例然后1A = =
/************************************************************** Problem: 4196 User: BPM136 Language: C++ Result: Accepted Time:7132 ms Memory:13316 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<bitset> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define efo(i,x) for(int i=last[x];i!=0;i=e[i].next) using namespace std; #define N 100005 struct edge { int y,next; }e[N]; int last[N],ne=0; int ls[N*4],rs[N*4],w[N*4],la[N*4],siz[N*4]; int fa[N],son[N],dep[N],top[N],dfn[N],en[N],nu=0; int n,m,root=1,ans=0; void dfs1(int x,int de,int pre) { dep[x]=de;fa[x]=pre;siz[x]=1; int ma=0,f=0; efo(i,x) { dfs1(e[i].y,de+1,x); siz[x]+=siz[e[i].y]; if(siz[e[i].y]>ma) { ma=siz[e[i].y]; f=e[i].y; } } son[x]=f; } void dfs2(int x,int t) { dfn[x]=++nu;top[x]=t; if(son[x])dfs2(son[x],t); efo(i,x) if(e[i].y!=son[x]) dfs2(e[i].y,e[i].y); en[x]=nu; } void pushup(int k) { ls[k]=ls[k<<1]; rs[k]=rs[k<<1|1]; w[k]=la[k]=0; } void buildsegtree(int k,int l,int r) { if(l==r) { rs[k]=ls[k]=l; w[k]=0;la[k]=-1; return; } int mid=(l+r)>>1; buildsegtree(k<<1,l,mid);buildsegtree(k<<1|1,mid+1,r); pushup(k); } void prework() { nu=0;dfs1(root,1,0);dfs2(root,root); buildsegtree(1,1,nu); } void pushlazy(int k) { if(la[k]==0) { w[k<<1]=w[k<<1|1]=0; la[k<<1]=la[k<<1|1]=0; } if(la[k]==1) { w[k<<1]=rs[k<<1]-ls[k<<1]+1; w[k<<1|1]=rs[k<<1|1]-ls[k<<1|1]+1; la[k<<1]=la[k<<1|1]=1; } la[k]=-1; } int change1seg(int k,int l,int r) { if(ls[k]==l&&rs[k]==r) { int num=r-l+1; int anss=num-w[k]; la[k]=1;w[k]=num; return anss; } int mid=(ls[k]+rs[k])>>1,flag=0; if(la[k]!=-1)pushlazy(k); if(r<=mid)flag=change1seg(k<<1,l,r); else { if(l>mid)flag=change1seg(k<<1|1,l,r); else flag=change1seg(k<<1,l,mid)+change1seg(k<<1|1,mid+1,r); } w[k]=w[k<<1]+w[k<<1|1]; return flag; } void change1(int k) { if(k==0)return; int t=top[k]; if(t==0)ans+=change1seg(1,dfn[k],dfn[k]); else ans+=change1seg(1,dfn[t],dfn[k]); change1(fa[t]); } int change0seg(int k,int l,int r) { if(ls[k]==l&&rs[k]==r) { int num=r-l+1; int anss=w[k]; w[k]=0;la[k]=0; return anss; } int mid=(ls[k]+rs[k])>>1;int flag=0; if(la[k]!=-1)pushlazy(k); if(r<=mid)flag=change0seg(k<<1,l,r); else { if(l>mid)flag=change0seg(k<<1|1,l,r); else flag=change0seg(k<<1,l,mid)+change0seg(k<<1|1,mid+1,r); } w[k]=w[k<<1]+w[k<<1|1]; return flag; } void change0(int k) { ans=change0seg(1,dfn[k],en[k]); } void add(int x,int y) { e[++ne].y=y;e[ne].next=last[x];last[x]=ne; } int main() { scanf("%d",&n); fo(i,1,n-1) { int x;scanf("%d",&x); fa[i+1]=x+1; add(x+1,i+1); } prework(); int t;scanf("%d",&t); while(t--) { char s[20];int ch;ans=0; scanf("%s%d",s,&ch);ch++; if(s[0]=='i')change1(ch); else change0(ch); printf("%d\n",ans); } return 0; }