zoukankan      html  css  js  c++  java
  • 【Codeforces】Gym100633 D. LWDB

    题解

    点分治,然后每个点上挂着一个距离不超过(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('
    ')
    #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();
    }
    
  • 相关阅读:
    sqlite错误 Abort due to constraint violation column id is not unique id没开启自动增长
    字符串转为日期类型
    XPTable 一行添加数据 如果想添加多行 可以使用for循环
    在逮捕异常的时候 可以获取e.MESSAGE里面的信息 然后判断是什么异常
    C# 加载图片image (C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法
    计算两个时间的前后 时间戳
    用C#语言写的多线程演示程序:两个线程,可以开始,可以暂停,可以恢复,可以清除。
    sqlite插入日期时候 出现18991230 0:00:00
    datagridview绑定dataset的时候 需要这一句
    WinForm 子线程修改主线程(UI线程)Control 【Z】
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10646749.html
Copyright © 2011-2022 走看看