1. 程式人生 > >【Codeforces】Gym100633 D. LWDB

【Codeforces】Gym100633 D. LWDB

\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