BZOJ 4196 [Noi2015]软件包管理器

来源:互联网 发布:java零基础骗局 编辑:程序博客网 时间:2024/06/05 17:37

NOI怎么会出现这么裸的题。。。

然而树剖写挂了这件事绝对不能忍。。。


#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<algorithm>using namespace std;const int maxn=100010;struct tree{int val,set;}t[maxn<<2];struct edge{int to,next;}e[maxn];int n,q,cnt,dfs_clock;int head[maxn],num[maxn],depth[maxn],out_time[maxn];int size[maxn],pere[maxn],top[maxn],son[maxn];int read(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();return x;}void insert(int a,int b){e[++cnt].to=b;e[cnt].next=head[a];head[a]=cnt;}void pushdown(int ro,int l,int r){int mid=l+r>>1;if(t[ro].set!=-1){t[ro<<1].set=t[ro].set;t[ro<<1|1].set=t[ro].set;t[ro<<1].val=(mid-l+1)*t[ro].set;t[ro<<1|1].val=(r-mid)*t[ro].set;t[ro].set=-1;}}void maintain(int ro){t[ro].val=t[ro<<1].val+t[ro<<1|1].val;}void setv(int ro,int L,int R,int val,int l,int r){if(l==L&&r==R){t[ro].val=val*(r-l+1);t[ro].set=val;return;}pushdown(ro,l,r);int mid=l+r>>1;if(R<=mid)setv(ro<<1,L,R,val,l,mid);else if(L>=mid+1)setv(ro<<1|1,L,R,val,mid+1,r);else setv(ro<<1,L,mid,val,l,mid),setv(ro<<1|1,mid+1,R,val,mid+1,r);maintain(ro);}int query(int ro,int L,int R,int l,int r){if(l==L&&r==R)return t[ro].val;pushdown(ro,l,r);int mid=l+r>>1;if(R<=mid)return query(ro<<1,L,R,l,mid);else if(L>=mid+1)return query(ro<<1|1,L,R,mid+1,r);return query(ro<<1,L,mid,l,mid)+query(ro<<1|1,mid+1,R,mid+1,r);}void dfs_init(int x){size[x]=1;son[x]=-1;for(int i=head[x];i;i=e[i].next){depth[e[i].to]=depth[x]+1;dfs_init(e[i].to);size[x]+=size[e[i].to];if(son[x]==-1||size[e[i].to]>size[son[x]])son[x]=e[i].to;}}void dfs_chain(int x,int fa,int tp){num[x]=++dfs_clock;pere[x]=fa;top[x]=tp;if(son[x]!=-1)dfs_chain(son[x],x,tp);for(int i=head[x];i;i=e[i].next)if(e[i].to!=son[x])dfs_chain(e[i].to,x,e[i].to);out_time[x]=dfs_clock;}int solve1(int x){int res=0;int pos=x,tp=top[x];do{tp=top[pos];res+=query(1,num[tp],num[pos],1,n);setv(1,num[tp],num[pos],1,1,n);pos=pere[tp];}while(tp);return depth[x]+1-res;}int solve2(int x){int res=query(1,num[x],out_time[x],1,n);setv(1,num[x],out_time[x],0,1,n);return res;}int main(){scanf("%d",&n);for(int i=1;i<n;i++)insert(read(),i);dfs_init(0);dfs_chain(0,0,0);for(int i=1;i<=n;i++)t[i].set=-1;scanf("%d",&q);while(q--){char op[2];scanf("%s",op);if(op[0]=='i')printf("%d\n",solve1(read()));elseprintf("%d\n",solve2(read()));}}