牛客國慶集訓派對Day6 I 清明夢超能力者黃YY
阿新 • • 發佈:2018-12-13
題意:
中文
思路:
染色部分樹鏈剖分即可
對於倒數第K次染色,轉化為正數第Q次,線段樹維護顏色即可。
程式碼:
#include <bits/stdc++.h> using namespace std; #define ls l,mid,rt*2 #define rs mid+1,r,rt*2+1 #define mi (l+r)/2 const int MAXN = 1e5 + 7; typedef struct Query { int u, v, c; }Query; vector <int> edge[MAXN]; vector <int> linkk[MAXN]; int n, m, k; int tsize[MAXN], dep[MAXN], hson[MAXN], father[MAXN]; int order[MAXN], transpos[MAXN]; int belong[MAXN], top[MAXN], cnt; int tim[MAXN * 4], lazyt[MAXN * 4], lazyT[MAXN * 4], st, en, tmin[MAXN * 4], tmax[MAXN * 4]; int col[MAXN * 4], ans[MAXN]; Query query[MAXN]; void ini() { for (int i = 1; i <= n; i++) { edge[i].clear(); belong[i] = 0; } linkk[1].clear(); dep[0] = -1; tsize[0] = 0; cnt = 0; top[1] = 1; return; } void dfs1(int now, int fa) { father[now] = fa; int len = edge[now].size(); dep[now] = dep[fa] + 1; tsize[now] = 1; hson[now] = 0; for (int i = 0; i < len; i++) { int pos = edge[now][i]; if (pos != fa) { dfs1(pos, now); tsize[now] += tsize[pos]; if (tsize[pos] > tsize[hson[now]]) hson[now] = pos; } } return; } void dfs2(int now, int bel, int fa) { belong[now] = bel; linkk[bel].push_back(now); int len = edge[now].size(); if (hson[now] != 0) dfs2(hson[now], bel, now); for (int i = 0; i < len; i++) { int pos = edge[now][i]; if (pos != now && pos != fa && pos != hson[now]) { cnt++; linkk[cnt].clear(); top[cnt] = pos; dfs2(pos, cnt, now); } } return; } void build(int l, int r, int rt) { lazyt[rt] = lazyT[rt] = col[rt] = tim[rt] = 0; if (l == r) return; int mid = mi; build(ls), build(rs); return; } void push_down_t(int rt) { if (lazyt[rt]) { tim[rt * 2] += lazyt[rt]; tim[rt * 2 + 1] += lazyt[rt]; lazyt[rt * 2] += lazyt[rt]; lazyt[rt * 2 + 1] += lazyt[rt]; } lazyt[rt] = 0; return; } void push_up_T(int rt) { tmin[rt] = min(tmin[rt * 2], tmin[rt * 2 + 1]); tmax[rt] = max(tmax[rt * 2], tmax[rt * 2 + 1]); return; } void updateT(int l, int r, int rt) { if (l > en || r < st) return; if (st <= l && r <= en) { tim[rt]++; lazyt[rt]++; return; } int mid = mi; push_down_t(rt); updateT(ls), updateT(rs); return; } void makeT(int l, int r, int rt) { if (l == r) { tim[rt] -= k; tmax[rt] = tmin[rt] = max(tim[rt], 0); return; } int mid = mi; push_down_t(rt); makeT(ls), makeT(rs); push_up_T(rt); return; } void solveT(int x, int y) { while (1) { if (top[belong[x]] == top[belong[y]]) { if (dep[x] > dep[y]) swap(x, y); st = transpos[x], en = transpos[y]; updateT(1, n, 1); break; } else { if (dep[top[belong[x]]] > dep[top[belong[y]]]) swap(x, y); st = transpos[top[belong[y]]], en = transpos[y]; updateT(1, n, 1); y = father[top[belong[y]]]; } } return; } void push_down_C(int rt) { if (col[rt]) { col[rt * 2] = col[rt]; col[rt * 2 + 1] = col[rt]; } col[rt] = 0; return; } void push_down_T(int rt) { if (lazyT[rt]) { tmax[rt * 2] -= lazyT[rt]; tmax[rt * 2 + 1] -= lazyT[rt]; tmin[rt * 2] -=lazyT[rt]; tmin[rt * 2 + 1] -=lazyT[rt]; lazyT[rt * 2] += lazyT[rt]; lazyT[rt * 2 + 1] += lazyT[rt]; } lazyT[rt] = 0; return; } void updateC(int l, int r, int rt, long long v) { if (l > en || r < st || tmax[rt] == 0) return; if (st <= l && r <= en && tmin[rt] > 0) { col[rt] = v; return; } int mid = mi; push_down_C(rt); push_down_T(rt); updateC(ls, v), updateC(rs, v); return; } void changeT(int l, int r, int rt) { if (l > en || r < st || tmax[rt] == 0) return; if (st <= l && r <= en && tmin[rt] > 0) { tmax[rt]--; tmin[rt]--; lazyT[rt]++; return; } int mid = mi; push_down_T(rt); changeT(ls), changeT(rs); push_up_T(rt); return; } void solveC(int x, int y, long long v) { while (1) { if (top[belong[x]] == top[belong[y]]) { if (dep[x] > dep[y]) swap(x, y); st = transpos[x], en = transpos[y]; updateC(1, n, 1, v); changeT(1, n, 1); break; } else { if (dep[top[belong[x]]] > dep[top[belong[y]]]) swap(x, y); st = transpos[top[belong[y]]], en = transpos[y]; updateC(1, n, 1, v); changeT(1, n, 1); y = father[top[belong[y]]]; } } return; } void makeC(int l, int r, int rt) { if (l == r) { ans[l] = col[rt]; return; } int mid = mi; push_down_C(rt); makeC(ls), makeC(rs); return; } int main() { scanf("%d%d%d", &n, &m, &k); k--; ini(); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); edge[x].push_back(y); edge[y].push_back(x); } dfs1(1, 0); dfs2(1, ++cnt, 0); int ppp = 0; for (int i = 1; i <= cnt; i++) { int len = linkk[i].size(); for (int j = 0; j < len; j++) { order[++ppp] = linkk[i][j]; transpos[linkk[i][j]] = ppp; } } build(1, n, 1); for (int i = 1; i <= m; i++) { scanf("%d%d%d", &query[i].u, &query[i].v, &query[i].c); solveT(query[i].u, query[i].v); } makeT(1, n, 1); for (int i = 1; i <= m; i++) { solveC(query[i].u, query[i].v, query[i].c); } makeC(1, n, 1); for (int i = 1; i <= n; i++) { printf("%d%c", ans[transpos[i]], " \n"[i == n]); } return 0; }