首页 > 数据库技术 > 详细

【Codeforces】Gym100633 D. LWDB

时间:2019-04-03 10:17:35      阅读:122      评论:0      收藏:0      [点我收藏+]

题解

点分治,然后每个点上挂着一个距离不超过\(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

原文:https://www.cnblogs.com/ivorysi/p/10646749.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!