[NOI2015]软件包管理器 树链剖分_线段树
没有太大难度,刷水有益健康
Code:
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 100002
using namespace std;
int read()
{
int f=1,x=0;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
void print(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9)print(x/10);
putchar(x%10+'0');
}
namespace Seg
{
#define lson (x << 1)
#define rson ((x << 1) | 1)
int sumv[maxn << 2], lazy[maxn << 2];
void mark_tag(int l, int r, int x, int delta)
{
sumv[x] = (r - l + 1) * delta, lazy[x] = delta;
}
void pushdown(int l, int r, int x)
{
if(lazy[x] == -1) return ;
int mid = (l + r) >> 1;
if(mid >= l) mark_tag(l, mid, lson, lazy[x]);
if(mid < r) mark_tag(mid + 1, r, rson, lazy[x]);
lazy[x] = -1;
}
int query(int l, int r, int x, int L, int R)
{
if(l >= L && r <= R)
{
return sumv[x];
}
pushdown(l, r, x);
int mid = (l + r) >> 1;
int t = 0;
if(L <= mid) t += query(l, mid, lson, L, R);
if(R > mid) t += query(mid + 1, r, rson, L, R);
return t;
}
void update(int l, int r, int x, int L, int R, int d)
{
if(l >= L && r <= R)
{
mark_tag(l, r, x, d);
return ;
}
pushdown(l, r, x);
int mid = (l + r) >> 1;
if(L <= mid) update(l, mid, lson, L, R, d);
if(R > mid) update(mid + 1, r, rson, L, R, d);
sumv[x] = sumv[lson] + sumv[rson];
}
};
int hd[maxn], to[maxn], nex[maxn], fa[maxn], siz[maxn], top[maxn], hson[maxn], dep[maxn];
int st[maxn], ed[maxn], dfn[maxn];
int edges, n, Q, root = 1, tim;
char str[100];
void add(int u, int v)
{
nex[++edges] = hd[u], hd[u] = edges, to[edges] = v;
}
void dfs1(int u)
{
siz[u] = 1, dep[u] = dep[fa[u]] + 1;
for(int i = hd[u]; i ; i = nex[i])
{
dfs1(to[i]), siz[u] += siz[to[i]];
if(siz[to[i]] > siz[hson[u]]) hson[u] = to[i];
}
}
void dfs2(int u, int tp)
{
dfn[u] = ++tim, top[u] = tp;
st[u] = tim;
if(hson[u])
dfs2(hson[u], tp);
for(int i = hd[u]; i ; i = nex[i])
{
if(to[i] != hson[u]) dfs2(to[i], to[i]);
}
ed[u] = tim;
}
int lookup(int x)
{
int t = 0;
while(x)
{
t += Seg :: query(1, n, 1, dfn[top[x]], dfn[x]);
Seg :: update(1, n, 1, dfn[top[x]], dfn[x], 1);
x = fa[top[x]];
}
return t;
}
int main()
{
// setIO("input");
n=read();
for(int i = 2; i <= n; ++i)
{
fa[i]=read(), ++fa[i], add(fa[i], i);
}
dfs1(1), dfs2(1, 1);
memset(Seg::lazy, -1, sizeof(Seg :: lazy));
Q=read();
while(Q--)
{
int u;
scanf("%s",str);
u=read();
u+=1;
if(str[0] == 'i')
{
print(dep[u] - lookup(u));
printf("\n");
}
if(str[0] == 'u')
{
print(Seg :: query(1, n, 1, st[u], ed[u]));
Seg :: update(1, n, 1, st[u], ed[u], 0);
printf("\n");
}
}
return 0;
}