P2146 [NOI2015]软件包管理器
2019-11-22 14:45 一只弱鸡丶 阅读(110) 评论(0) 编辑 收藏 举报这道题也是裸题0.0
#pragma GCC optimize("O3") #include <bits/stdc++.h> #include <tr1/unordered_map> using namespace std; #define ll long long #define re register #define pb push_back #define fi first #define se second const int N=1e6+10; const int mod=998244353; void read(int &a) { a=0;int d=1;char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } struct note{int l,r,ma,mi,lazy;}tree[N<<1]; int top[N],siz[N],cnt,rt=1,id[N],son[N],f[N],dep[N]; vector <int> v[N]; void dfs1(int x) { siz[x]=1,dep[x]=dep[f[x]]+1; for(auto i:v[x]) { if(i!=f[x]) { f[i]=x,dfs1(i); siz[x]+=siz[i]; if(siz[son[x]]<siz[i]) son[x]=i; } } } void dfs2(int x,int tp) { top[x]=tp,id[x]=++cnt; if(son[x]) dfs2(son[x],tp); for(auto i:v[x]) if(i!=son[x]&&i!=f[x]) dfs2(i,i); } void build(int l,int r,int now) { tree[now].l=l,tree[now].r=r,tree[now].lazy=-1; if(l==r) {tree[now].ma=1,tree[now].mi=0;return;} int m=l+r>>1; build(l,m,now<<1),build(m+1,r,now<<1|1); tree[now].ma=tree[now<<1].ma+tree[now<<1|1].ma; tree[now].mi=tree[now<<1].mi+tree[now<<1|1].mi; } void work(int now,int k) { if(!k) tree[now].ma=tree[now].r-tree[now].l+1,tree[now].mi=0; else tree[now].ma=0,tree[now].mi=tree[now].r-tree[now].l+1; tree[now].lazy=k; } void pushdown(int now) { work(now<<1,tree[now].lazy); work(now<<1|1,tree[now].lazy); tree[now].lazy=-1; } void modify(int l,int r,int now,int k) { if(tree[now].l>=l&&tree[now].r<=r) {work(now,k);return;} if(tree[now].lazy!=-1) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) modify(l,r,now<<1,k); if(m<r) modify(l,r,now<<1|1,k); tree[now].ma=tree[now<<1].ma+tree[now<<1|1].ma; tree[now].mi=tree[now<<1].mi+tree[now<<1|1].mi; } int query(int l,int r,int now,int k) { int ans=0; if(tree[now].l>=l&&tree[now].r<=r) {return k==1?tree[now].mi:tree[now].ma;} if(tree[now].lazy!=-1) pushdown(now); int m=tree[now].l+tree[now].r>>1; if(m>=l) ans+=query(l,r,now<<1,k); if(m<r) ans+=query(l,r,now<<1|1,k); return ans; } int update(int x,int y)///安装,ma是0的个数 { int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=query(id[top[x]],id[x],1,0); modify(id[top[x]],id[x],1,1); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans+=query(id[x],id[y],1,0); modify(id[x],id[y],1,1); return ans; } char op[10]; int main() { int n,m;read(n); for(re int i=2,x;i<=n;i++) read(x),x++,v[i].pb(x),v[x].pb(i); dfs1(rt),dfs2(rt,rt),build(1,n,1); read(m); for(re int i=1,x;i<=m;i++) { scanf("%s %d",op,&x);x++; if(op[0]=='i') printf("%d\n",update(x,1)); else printf("%d\n",query(id[x],id[x]+siz[x]-1,1,1)),modify(id[x],id[x]+siz[x]-1,1,0); } return 0; }