NOI2015 Package Manager
Title Description
OSX and Linux users to certain user package manager will not be unfamiliar. Through the package manager, you can install a package by a command line, then Package Manager will help you download software packages from source, and automatically resolve all the dependencies (ie, download and install the installation package depends other packages) to complete all of the configuration. apt-get, Fedora / CentOS using yum Debian / Ubuntu uses, as well as homebrew available under OSX are excellent package manager.
Enter a description
The first line of the input file contains a positive integer n, the total package. Packages are numbered starting from zero.
Output Description
Output file including q rows.
Sample input
Sample Output
Obviously this is a tree , so let's be the skilled throwing feces tree chain segment tree split + ~
And only need to record how many software updates within the range of installation on the line
Update subtree time, because the distribution point of the segment tree is actually a heavy chain DFS order of priority
So that the update interval subtree is [id [x], id [x] + size [x] -1] friends
Pay several times before A
A previous RE
1e5 2e5 change becomes TLE (but do not know why RE )
Then find the topic of inquiry and change are tied together
Put the query and modify the change to a function in
Then A friends ~
#include <iostream> #include <cstdio> #include <cstring> #include <string> #define M 200010 using namespace std; int n,q,size[M],dep[M],fa[M],rk[M],id[M]; int k,cnt,head[M],son[M],top[M],sum[M*2],lazy[M]; struct node { int to,next; }e[M]; void add(int x,int y) { e[k].to = y; e[k].next = head[x]; head[x] = k++; } void init() { k=0; cnt=0; for (int i=0;i<=n;i++) { size[i] = son[i] = 0; head[i] = lazy[i] = -1; sum[i] = sum[i+n] = 0; } } void dfs1(int s,int d) { dep[s] = d; size[s] = 1; for (int i=head[s];~i;i=e[i].next) if ( e[i].to != fa[s] ) { dfs1(e[i].to,d+1); size[s] += size[e[i].to]; if ( size[e[i].to] > size[son[s]] ) son[s] = e[i].to; } } void dfs2(int s,int t) { top[s] = t; id[s] = ++cnt; rk[cnt] = s; if ( !son[s] ) return; dfs2(son[s],t); for (int i=head[s];~i;i=e[i].next) if ( e[i].to != fa[s] && e[i].to != son[s] ) dfs2(e[i].to,e[i].to); } void pushup(int x) { sum[x] = sum[x*2] + sum[x*2+1]; } void pushdown(int l,int r,int x) { if ( lazy[x] != -1 ) { int mid = (l+r)/2; sum[x*2] = (mid-l+1)*lazy[x]; lazy[x*2] = lazy[x]; sum[x*2+1] = (r-mid)*lazy[x]; lazy[x*2+1] = lazy[x]; lazy[x] = -1; } } void update(int L,int R,int x,int l,int r,int a) { if ( l<=L&&R<=r ) { lazy[x] = a; sum[x] = a*(R-L+1); return; } pushdown(L,R,x); int mid=(L+R)/2; if ( l<=mid ) update(L,mid,x*2,l,r,a); if ( mid < r ) update(mid+1,R,x*2+1,l,r,a); pushup(x); } void updates(int x) { while ( top[x] != 1 ) { update(1,n,1,id[top[x]],id[x],1); x=fa[top[x]]; } update(1,n,1,1,id[x],1); } int query(int L,int R,int x,int l,int r,int a) { int ret = 0; if ( l<=L&&R<=r ) { ret = sum[x]; sum[x] = a*(R-L+1); lazy[x] = a; return ret; } pushdown(L,R,x); int mid = (L+R)/2; if ( l<=mid ) ret+=query(L,mid,x*2,l,r,a); if ( mid < r) ret+=query(mid+1,R,x*2+1,l,r,a); pushup(x); return ret; } int Que(int x) { int ret=0; while ( top[x] != 1 ) { ret+=query(1,n,1,id[top[x]],id[x],1); x=fa[top[x]]; } ret += query(1,n,1,1,id[x],1); return ret; } int main() { cin>>n; init(); fa[1] = 1; for (int i=2;i<=n;i++) { scanf("%d",&fa[i]); fa[i]++; add(fa[i],i); } dfs1(1,1); dfs2(1,1); char op[2]; int a,ans; cin>>q; for (int i=1;i<=q;i++) { scanf("%s %d",op,&a); a++; if ( op[0] == 'i' ) { ans = dep[a] - Que(a); printf("%d\n",ans); } else { ans = query(1,n,1,id[a],id[a]+size[a]-1,0); printf("%d\n",ans); } } return 0; }