- 题意:
给n个点(1-n)的树,1为根节点,每个点初始值为1。q次操作:1、C操作:每次给一个标号x,将x节点的值取非 2、Q操作:给x,求x子树的点值之和 - 分析:
这个题目关键在于将树上的节点放到一维来处理,这样就可以用树状数组或者线段树来解决了。处理时使用dfs,对每个节点都进行编号。
树状数组:
const int MAXN = 100001;
int nxt[MAXN << 1], val[MAXN << 1], head[MAXN], tot = 0;
void adj_init(int n)
{
REP(i, n)
head[i] = -1;
tot = 0;
}
void adj_ins(int u, int v)
{
val[tot] = v;
nxt[tot] = head[u];
head[u] = tot++;
}
int dfs_clock;
int lft[MAXN], rht[MAXN];
void dfs(int u, int fa)
{
lft[u] = dfs_clock++;
for (int i = head[u]; ~i; i = nxt[i])
{
if (val[i] != fa)
dfs(val[i], u);
}
rht[u] = dfs_clock - 1;
}
int tree[MAXN];
inline int lowbit(int x)
{
return x & (-x);
}
inline void add(int p, int v)
{
for (; p < MAXN; p += lowbit(p))
tree[p] += v;
}
inline int sum(int p)
{
int ret = 0;
for (; p > 0; p -= lowbit(p))
ret += tree[p];
return ret;
}
int ipt[MAXN];
int main()
{
int n, q;
while (~RI(n))
{
adj_init(n + 1);
dfs_clock = 1;
CLR(tree, 0);
FE(i, 1, n)
ipt[i] = 1;
REP(i, n - 1)
{
int a, b;
RII(a, b);
adj_ins(a, b);
adj_ins(b, a);
}
dfs(1, -1);
RI(q);
FE(kase, 1, q)
{
char op; int v;
scanf(" %c %d", &op, &v);
int l = lft[v], r = rht[v];
if (op == 'Q')
{
WI(r - l + 1 - sum(r) + sum(l - 1));
}
else
{
int ad = 1;
if (ipt[v] == 0)
ad = -1;
ipt[v] ^= 1;
add(l, ad);
}
}
}
return 0;
}
const int MAXN = 100001;
int nxt[MAXN << 1], val[MAXN << 1], head[MAXN], tot = 0;
void adj_init(int n)
{
REP(i, n)
head[i] = -1;
tot = 0;
}
void adj_ins(int u, int v)
{
val[tot] = v;
nxt[tot] = head[u];
head[u] = tot++;
}
int dfs_clock;
int lft[MAXN], rht[MAXN];
void dfs(int u, int fa)
{
lft[u] = dfs_clock++;
for (int i = head[u]; ~i; i = nxt[i])
{
if (val[i] != fa)
dfs(val[i], u);
}
rht[u] = dfs_clock - 1;
}
#define lson rt << 1
#define rson rt << 1 | 1
struct Node
{
int l, r, m;
int sum;
} nd[MAXN << 2];
void pushUP(int rt)
{
nd[rt].sum = nd[lson].sum + nd[rson].sum;
}
void build(int l, int r, int rt)
{
nd[rt].l = l; nd[rt].r = r; nd[rt].m = (l + r) >> 1;
if (l == r)
nd[rt].sum = 1;
else
{
build(l, nd[rt].m, lson);
build(nd[rt].m + 1, r, rson);
pushUP(rt);
}
}
void add(int p, int v, int rt)
{
if (nd[rt].l == nd[rt].r)
nd[rt].sum += v;
else
{
if (p <= nd[rt].m)
add(p, v, lson);
else
add(p, v, rson);
pushUP(rt);
}
}
int query(int L, int R, int rt)
{
if (L <= nd[rt].l && nd[rt].r <= R)
return nd[rt].sum;
else
{
int ret = 0;
if (L <= nd[rt].m)
ret += query(L, R, lson);
if (R > nd[rt].m)
ret += query(L, R, rson);
return ret;
}
}
int ipt[MAXN];
int main()
{
int n, q;
while (~RI(n))
{
adj_init(n + 1);
dfs_clock = 1;
build(1, n, 1);
FE(i, 1, n)
ipt[i] = 1;
REP(i, n - 1)
{
int a, b;
RII(a, b);
adj_ins(a, b);
adj_ins(b, a);
}
dfs(1, -1);
RI(q);
FE(kase, 1, q)
{
char op; int p;
scanf(" %c %d", &op, &p);
int l = lft[p], r = rht[p];
if (op == 'Q')
{
WI(query(l, r, 1));
}
else
{
int ad = -1;
if (ipt[p] == 0)
ad = 1;
ipt[p] ^= 1;
add(l, ad, 1);
}
}
}
return 0;
}