題意:給出一棵樹,每個點有一個點權,問一x爲根的子樹中有多少種權重恰好出現了k次。
懶了,直接貼題解,況且本來也不是自己寫出來的
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<cmath>
#include<map>
using namespace std;
const int maxn = 100010;
struct node {
int be, ne;
void init(int b, int e) {
be = b;
ne = e;
}
} buf[maxn * 2];
struct query {
int id, from, to;
bool operator <(const query &oth) const {
return to < oth.to;
}
} qq[maxn];
int E[maxn], len;
void add(int a, int b) {
buf[len].init(b, E[a]);
E[a] = len++;
buf[len].init(a, E[b]);
E[b] = len++;
}
int cnt, id[maxn];
int ss[maxn];
int color[maxn], ans[maxn], cas, n, k, a, b, m;
map<int, int> mp;
int head[maxn], nxt[maxn], last[maxn], num[maxn];
void init(int n) {
for (int i = 1; i <= n; i++) {
E[i] = -1;
qq[i].from = qq[i].to = 0;
qq[i].id = i;
ss[i] = num[i] = head[i] = 0;
}
mp.clear();
len = 0;
cnt = 0;
}
void dfs(int a) {
qq[a].from = qq[a].to = ++cnt;
id[cnt] = a;
for (int i = E[a]; i != -1; i = buf[i].ne) {
int b = buf[i].be;
if (qq[b].from)
continue;
dfs(b);
qq[a].to = qq[b].to;
}
}
int lowbit(int k) {
return (k & -k);
}
void inc(int i, int k) {
while (i <= n) {
ss[i] += k;
i += lowbit(i);
}
}
int get(int i) {
int res = 0;
while (i > 0) {
res += ss[i];
i -= lowbit(i);
}
return res;
}
void update(int from, int to, int v) {
inc(from, v);
inc(to + 1, -v);
}
int main() {
scanf("%d", &cas);
for (int c = 1; c <= cas; c++) {
printf("Case #%d:\n", c);
scanf("%d%d", &n, &k);
init(n);
for (int i = 1; i <= n; i++) {
scanf("%d", color + i);
mp[color[i]] = 0;
}
int cnt = 0;
for (map<int, int>::iterator it = mp.begin(); it != mp.end(); it++)
(*it).second = ++cnt;
for (int i = 1; i <= n; i++)
color[i] = mp[color[i]];
for (int i = 1; i < n; i++) {
scanf("%d %d", &a, &b);
add(a, b);
}
dfs(1);
sort(qq + 1, qq + n + 1);
int p = 0;
for (int i = 1; i <= n; i++) {
while (p < qq[i].to) {
p++;
int t = color[id[p]];
num[t]++;
nxt[last[t]] = p;
last[t] = p;
if (head[t] == 0)
head[t] = p;
if (num[t] == k)
update(1, head[t], 1);
if (num[t] == k + 1) {
update(1, head[t], -1);
update(head[t] + 1, nxt[head[t]], 1);
}
if (num[t] > k + 1) {
update(head[t] + 1, nxt[head[t]], -1);
head[t] = nxt[head[t]];
update(head[t] + 1, nxt[head[t]], 1);
}
}
ans[qq[i].id] = get(qq[i].from);
}
scanf("%d", &m);
while (m--) {
scanf("%d", &a);
printf("%d\n", ans[a]);
}
if (c != cas)
printf("\n");
}
return 0;
}