【Codeforces】Gym100633 D. LWDB
阿新 • • 發佈:2019-04-03
\n endif bit init ear enter long pan clu
題解
點分治,然後每個點上掛著一個距離不超過\(a_{i}\)的顏色改成\(c\)
用一個單調棧維護距離單調遞減,每次查詢在每個包括這個點的分治中心的單調棧上二分,找到修改最靠前的顏色作為這個點的顏色
代碼
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define MAXN 200005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 +c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } struct ch { int id,d,c; }; struct node { int to,next,val; }E[MAXN * 2]; int N,head[MAXN],sumE,d[MAXN],M; bool vis[MAXN]; vector<int> aux[MAXN],dep[MAXN],poi; vector<ch> sta[MAXN]; void add(int u,int v,int c) { E[++sumE].to = v; E[sumE].next = head[u]; E[sumE].val = c; head[u] = sumE; } int Calc_G(int st) { static int fa[MAXN],son[MAXN],siz[MAXN],que[MAXN],ql,qr; ql = 1,qr = 0; que[++qr] = st;son[st] = 0;siz[st] = 1;fa[st] = 0; while(ql <= qr) { int u = que[ql++]; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(!vis[v] && v != fa[u]) { que[++qr] = v; siz[v] = 1;son[v] = 0;fa[v] = u; } } } int res = que[qr]; for(int i = qr ; i >= 1 ; --i) { int u = que[i]; if(fa[u]) { siz[fa[u]] += siz[u]; son[fa[u]] = max(son[fa[u]],siz[u]); } son[u] = max(son[u],qr - siz[u]); if(son[u] < son[res]) res = u; } return res; } void dfs_for_dep(int u,int fa) { poi.pb(u); for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(!vis[v] && v != fa) { d[v] = d[u] + E[i].val; dfs_for_dep(v,u); } } } void dfs_divide(int u) { int G = Calc_G(u); vis[G] = 1; sta[G].pb((ch){0,1000000000,0}); d[G] = 0;poi.clear(); dfs_for_dep(G,0); for(int i = 0 ; i < poi.size() ; ++i) { aux[poi[i]].pb(G); dep[poi[i]].pb(d[poi[i]]); } for(int i = head[G] ; i ; i = E[i].next) { int v = E[i].to; if(!vis[v]) dfs_divide(v); } } void Init() { read(N); int u,v,c; for(int i = 1 ; i < N ; ++i) { read(u);read(v);read(c); add(u,v,c);add(v,u,c); } dfs_divide(1); } void Change(int id,int x,int d,int c) { for(int i = aux[x].size() - 1 ; i >= 0 ; --i) { int u = aux[x][i],t = d - dep[x][i]; if(t < 0) continue; while(sta[u].size()) { ch l = sta[u].back(); if(l.d <= t) sta[u].pop_back(); else break; } sta[u].pb((ch){id,t,c}); } } int Query(int x) { int id = 0,c = 0; for(int i = aux[x].size() - 1 ; i >= 0 ; --i) { int u = aux[x][i],d = dep[x][i]; int L = 0,R = sta[u].size() - 1; while(L < R) { int mid = (L + R + 1) >> 1; if(sta[u][mid].d >= d) L = mid; else R = mid - 1; } if(sta[u][L].id > id) {id = sta[u][L].id;c = sta[u][L].c;} } return c; } void Solve() { read(M); int op,v,d,c; for(int i = 1 ; i <= M ; ++i) { read(op);read(v); if(op == 1) { read(d);read(c); Change(i,v,d,c); } else { out(Query(v));enter; } } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }
【Codeforces】Gym100633 D. LWDB