軟體包管理器 T21 D71
阿新 • • 發佈:2021-10-21
軟體包管理器 T21 D71
思路
樹剖+線段樹
每次in操作詢問此節點到根節點路徑權值和,再把路徑節點權值全部變為1
un操作詢問當前節點子樹權值和,再把子樹權值變為0
#include<bits/stdc++.h> #define ll long long #define pii pair<int,int> #define fi first #define se second #define pb push_back #define si size() #define ls (p<<1) #define rs ((p<<1)|1) #define mid (t[p].l+t[p].r)/2 using namespace std; ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;} inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');} const int qs=1e5+7; const int mod=1e9; ll n,m,q,a[qs]; int dep[qs],f[qs],fr[qs],sz[qs],son[qs],top[qs],cnt=0; vector<int> v[qs]; pii id[qs]; struct Tree{ ll val,add; int l,r; #define l(x) t[x].l #define r(x) t[x].r #define val(x) t[x].val #define add(x) t[x].add }t[qs<<2]; void pushup(int p){ val(p)=(val(ls)+val(rs))%mod;} void down(int p){ if(add(p)==-1) return; val(ls)=(add(p)*(r(ls)-l(ls)+1))%mod; val(rs)=(add(p)*(r(rs)-l(rs)+1))%mod; add(ls)=(add(p))%mod; add(rs)=(add(p))%mod; add(p)=-1; } void build(int p,int l,int r){ l(p)=l,r(p)=r;add(p)=-1; if(l==r){ val(p)=0; return; } build(ls,l,mid); build(rs,mid+1,r); pushup(p); // cout<<"l="<<l<<" r="<<r<<" val="<<val(p)<<"\n"; } void update(int p,int l,int r,ll val){ if(l<=l(p)&&r>=r(p)){ val(p)=(val*(r(p)-l(p)+1))%mod; add(p)=(val)%mod; //cout<<"l="<<l(p)<<" r="<<r(p)<<" val="<<val(p)<<"\n"; return; } down(p); if(l<=mid) update(ls,l,r,val); if(r>mid) update(rs,l,r,val); pushup(p); } ll ask(int p,int l,int r){ if(l<=l(p)&&r>=r(p)) return val(p); down(p); ll val=0; if(l<=mid) val=(val+ask(ls,l,r))%mod; if(r>mid) val=(val+ask(rs,l,r))%mod; return val; } void dfs(int x,int fa){ dep[x]=dep[fa]+1; f[x]=fa; sz[x]=1; son[x]=0; int ms=0; for(int i=0;i<v[x].si;++i){ int p=v[x][i]; if(p==fa) continue; dfs(p,x); sz[x]+=sz[p]; if(sz[p]>ms) son[x]=p,ms=sz[p]; } } void dfn(int x,int po){ id[x].fi=++cnt; fr[cnt]=x; top[x]=po; if(!son[x]) { id[x].se=cnt; return; } dfn(son[x],po); for(int i=0;i<v[x].si;++i){ int p=v[x][i]; if(p==f[x]||p==son[x]) continue; dfn(p,p); } id[x].se=cnt; } void updRange(int x,int y,ll k){ k%=mod; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); update(1,id[top[x]].fi,id[x].fi,k); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); update(1,id[x].fi,id[y].fi,k); } ll qRange(int x,int y){ ll ans=0,res; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); res=ask(1,id[top[x]].fi,id[x].fi); ans=(ans+res)%mod; x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); res=ask(1,id[x].fi,id[y].fi); ans=(ans+res)%mod; return ans; } int main(){ scanf("%lld\n",&n); ll x; for(int i=1;i<n;++i){ scanf("%lld\n",&x); v[x].pb(i); } dfs(0,0); dfn(0,0); build(1,1,n); scanf("%lld",&m); while(m--){ char op[20]; scanf("%s%lld",op,&x); ll ans; if(op[0]=='i'){ ans=dep[x]-qRange(0,x); updRange(0,x,1); } else{ ans=ask(1,id[x].fi,id[x].se); update(1,id[x].fi,id[x].se,0); } printf("%lld\n",ans); } return 0; } /* */