Open cup 2019 Korea Gym 102059A Coloring Roads
阿新 • • 發佈:2020-07-09
樹鏈剖分。
先做輕重鏈剖分後,維護每一條鏈上的資訊。初始樹為空。
以每一條重鏈的頭top為基點,建立單調棧。棧內維護,從大到小,該鏈上修改的深度,以及對應顏色。
每一次修改,如果棧內有比他淺的點,即,若我們把當前的顏色塗上,會使得之前的顏色覆蓋掉,故我們清除掉該顏色。不斷彈棧,直到為空或者棧頂比他深度深。若棧頂比他深,優先修改,當前的顏色的深度,即,把深度更深的顏色,給修改為空,我們才能重新計算並且塗上顏色。
然後每一個跳top的father的時候,我們單獨把所有的,這樣的top-father拿出來計算即可。
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<stack> #include<vector> #include<queue> #include<set> #include<bitset> #include<map> //#include<regex> #include<cstdio> #include <iomanip> #pragma GCC optimize(2) #define up(i,a,b) for(int i=a;i<b;i++) #define dw(i,a,b) for(int i=a;i>b;i--) #define upd(i,a,b) for(int i=a;i<=b;i++) #define dwd(i,a,b) for(int i=a;i>=b;i--) //#define local typedef long long ll; typedef unsigned long long ull; const double esp = 1e-6; const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int inf = 1e9; using namespace std; int read() { char ch = getchar(); int x = 0, f = 1; while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } typedef pair<int, int> pir; #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lrt root<<1 #define rrt root<<1|1 const int N = 2e5 + 10; vector<int>g[N]; int u, v, n, q, c, m, cr; int col[N], cnt[N]; int id_s = 0; int id[N], siz[N], son[N], top[N], f[N]; //int eg[N]; //int rk[N]; vector<pir>s[N]; void dfs1(int now, int fa, int d) { //rk[u] = ++tot_; f[now] = fa; //dep[u] = d; siz[now] = 1; for (auto k : g[now]) { if (k == fa)continue; dfs1(k, now, d + 1); siz[now] += siz[k]; if (siz[son[now]] < siz[k]) { son[now] = k; } } return; } void dfs2(int now, int tp) { id[now] = ++id_s; top[now] = tp; if (son[now]) { dfs2(son[now], tp); } for (auto k : g[now]) { if (k == f[now] || k == son[now])continue; dfs2(k, k); } return; } void modify(int val, int c) { cnt[col[c]]--; col[c] += val; cnt[col[c]]++; } void update(int l, int r, int c) { } int main() { scanf("%d %d %d", &n, &cr, &q); upd(i, 1, n - 1) { scanf("%d %d", &u, &v); g[u].push_back(v); g[v].push_back(u); } cnt[0] = cr; //col[0] = n - 1; //num[n - 1] = 1; dfs1(1, 0, 1); dfs2(1, 1); while (q--) { scanf("%d %d %d", &u, &v, &m); while (u) { int tp = top[u]; int pr = id[tp] - 1; while (!s[tp].empty() && s[tp].back().first < id[u]) { pir temp = s[tp].back(); s[tp].pop_back(); modify(-(temp.first - pr), temp.second); pr = temp.first; } if (!s[tp].empty()) { modify(-(id[u] - pr), s[tp].back().second); } s[tp].push_back(make_pair(id[u], v)); modify(id[u] - id[tp] + 1, v); u = f[tp]; //if (u == 0)break; } int ans = cnt[m]; if (col[v] == m)ans--; else if (col[v] == m + 1)ans++; printf("%d\n", ans); } return 0; }