有一棵n个节点的树(n <= 250000 ),根节点为编号为1;初始时树上所有边的颜色为白色。
现给出 n+m-1 组询问,共有“ W ", " A " 两种方式的询问:
W x :表示查询从根节点出发到节点x的简单路径上白色边的数量。
A x y: 表示一条边(x,y)被修改为黑色。数据保证每条边只会被修改一次。
(m <= 250000)
我的思路:转成dfn序,在序列上用树状数组维护即可
看了下题解,我的思路和题解一样,但一直TLE,怎么卡都卡不过去......
求大佬答疑 QwQ
#include <cstdio>
#define lowbit(x) x & -x
using namespace std;
const int maxn = 250020;
int n;
int dfn[maxn], dfcnt, dep[maxn], cnt[maxn];
int head[maxn], nxt[maxn], ver[maxn], tot;
int tree[maxn];
//inline void swap(int &a, int &b) { a ^= b, b ^= a, a ^= b; }
inline void addline(int x, int y) { ver[++tot] = y, nxt[tot] = head[x], head[x] = tot; }
void add(int pos, int v) {
for (register int i = pos; i <= n; i += lowbit(i)) tree[i] += v;
}
int sum(int pos) {
int ans = 0;
for (register int i = pos; i; i -= lowbit(i)) ans += tree[i];
return ans;
}
void dfs1(int x, int d) {
dfn[x] = ++dfcnt;
cnt[x] = 1;
dep[x] = d;
add(dfcnt, dep[x]);
add(dfcnt + 1, -dep[x]);
for (int i = head[x]; i; i = nxt[i]) {
dfs1(ver[i], d + 1);
cnt[x] += cnt[ver[i]];
}
}
int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while ('0' <= c && c <= '9') num = num * 10 + c - '0', c = getchar();
return num;
}
int main() {
// freopen("meg.in", "r", stdin);
// freopen("meg.out", "w", stdout);
n = read();
for (int i = 1; i < n; i++) {
int ui = read(), vi = read();
addline(ui, vi);
}
dfs1(1, 0);
int m = read();
int q = n + m - 1;
while (q--) {
char c;
scanf("%c", &c);
if (c == 'W') {
int a = read();
printf("%d\n", sum(dfn[a]));
} else {
int a = read(), b = read();
// if (a > b)
// swap(a, b);
add(dfn[b], -1);
add(dfn[b] + cnt[b], 1);
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}