题意:
给出一颗树,初始的颜色都是0,现在有两种操作。1、询问现在树有多少同种颜色组成的树;2、将x点的颜色改成y
题解:
这题乱搞题,思路是这样的,开始同颜色数的个数ans=1,每次给某个点改颜色直接影响的就是其父亲和孩子。那么只要考虑两点:
1、对父亲的影响,对于如果现在的节点颜色等于父亲并且变换后的颜色不等于父亲,那么必然会增加一课同颜色子树。如果现在节点的颜色不等于父亲而变换后等于父亲,那么必然要减少一课同颜色子树。
2、对孩子的影响,和父亲的道理是一样样的!如果颜色变成某些孩子的颜色,对应多少个孩子就减少多少棵子树,但是和原来颜色孩子子树就解放了,所以肯定会增加对应的子树个数。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #include<map> #include<set> #include<stack> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef unsigned long long ull; const int oo = 0x3f3f3f3f; const ll OO = 0x3f3f3f3f3f3f3f3f; const double eps = 1e-9; #define lson rt<<1 #define rson rt<<1|1 void cmax(int& a, int b){ if (b > a)a = b; } void cmin(int& a, int b){ if (b < a)a = b; } void cmax(ll& a, ll b){ if (b > a)a = b; } void cmin(ll& a, ll b){ if (b < a)a = b; } void cmax(double& a, double b){ if (a - b < eps) a = b; } void cmin(double& a, double b){ if (b - a < eps) a = b; } void add(int& a, int b, int mod){ a = (a + b) % mod; } void add(ll& a, ll b, ll mod){ a = (a + b) % mod; } const ll MOD = 1000000007; const int maxn = 110000; int col[maxn], fa[maxn]; map<int, int>g[maxn]; struct EDGE{ int v, next; }E[maxn << 1]; int head[maxn], tol; void Init(){ memset(head, -1, sizeof head); memset(col, 0, sizeof col); tol = 0; } void add_edge(int u, int v){ E[tol].v = v; E[tol].next = head[u]; head[u] = tol++; } int main(){ //freopen("E:\\read.txt", "r", stdin); int T, n, q, cas = 1, u, v, op, x, y, ans; scanf("%d", &T); while (T--){ scanf("%d", &n); Init(); for (int i = 1; i < n; i++){ scanf("%d %d", &u, &v); add_edge(u, v); add_edge(v, u); g[i].clear(); } g[n].clear(); fa[1] = -1; queue<int>Q; Q.push(1); while (!Q.empty()){ int u = Q.front(); Q.pop(); for (int i = head[u]; i != -1; i = E[i].next){ int v = E[i].v; if (v == fa[u]) continue; fa[v] = u; g[u][0]++; Q.push(v); } } scanf("%d", &q); printf("Case #%d:\n", cas++); ans = 1; while (q--){ scanf("%d", &op); if (op == 1) printf("%d\n", ans); else{ scanf("%d %d", &x, &y); if (col[x] == y) continue; ans -= g[x][y]; ans += g[x][col[x]]; if (fa[x] != -1){ if (col[x] == col[fa[x]]) ans++; if (y == col[fa[x]]) ans--; g[fa[x]][y]++; g[fa[x]][col[x]]--; } col[x] = y; } } } return 0; }