zoukankan      html  css  js  c++  java
  • 「CTSC2008」网络管理

    「CTSC2008」网络管理

    传送门
    整体二分做法,应该和这题一样的吧。
    就是把序列换成树,第 (k) 小换成第 (k) 大。
    然后就切了。。。
    参考代码:

    #include <algorithm>
    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    using namespace std;
    template < class T > inline void read(T& s) {
        s = 0; int f = 0; char c = getchar();
        while ('0' > c || c > '9') f |= c == '-', c = getchar();
        while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
        s = f ? -s : s;
    }
    
    const int _ = 80005;
    
    int tot, head[_]; struct Edge { int ver, nxt; } edge[_ << 1];
    inline void Add_edge(int u, int v) { edge[++tot] = (Edge) { v, head[u] }, head[u] = tot; }
    
    int n, m, a[_], ans[_], tr[_];
    int num, q; struct node { int k, x, y, id; } t[_ << 1], tt1[_ << 1], tt2[_ << 1];
    int dep[_], siz[_], son[_], fa[_], dfn[_], top[_];
    
    inline void update(int x, int v) { for (rg int i = x; i <= n; i += i & -i) tr[i] += v; }
    
    inline int query(int x) { int res = 0; for (rg int i = x; i >= 1; i -= i & -i) res += tr[i]; return res; }
    
    inline int Query(int x, int y) {
        int fx = top[x], fy = top[y], res = 0;
        while (fx != fy) {
        	if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
        	res += query(dfn[x]) - query(dfn[fx] - 1), x = fa[fx], fx = top[x];
        }
        if (dep[x] > dep[y]) swap(x, y);
        res += query(dfn[y]) - query(dfn[x] - 1);
        return res;
    }
    
    inline void dfs(int u, int f) {
        dep[u] = dep[f] + 1, siz[u] = 1, fa[u] = f;
        for (rg int i = head[u]; i; i = edge[i].nxt) {
        	int v = edge[i].ver; if (v == f) continue ;
        	dfs(v, u), siz[u] += siz[v];
        	if (siz[son[u]] < siz[v]) son[u] = v;
        }
    }
    
    inline void dfs(int u, int f, int topf) {
        dfn[u] = ++dfn[0], top[u] = topf;
        if (son[u]) dfs(son[u], u, topf);
        for (rg int i = head[u]; i; i = edge[i].nxt) {
    	    int v = edge[i].ver; if (v == f || v == son[u]) continue ;
    	    dfs(v, u, v);
        }
    }
    
    inline void solve(int ql, int qr, int l, int r) {
        if (ql > qr || l > r) return ;
        if (l == r) { for (rg int i = ql; i <= qr; ++i) if (t[i].id) ans[t[i].id] = l; return ; }
        int mid = (l + r) >> 1, p1 = 0, p2 = 0;
        for (rg int i = ql; i <= qr; ++i) {
    	    if (t[i].id == 0) {
        	    if (t[i].y <= mid) tt1[++p1] = t[i]; else update(dfn[t[i].x], t[i].k), tt2[++p2] = t[i];
        	} else {
    	        int cnt = Query(t[i].x, t[i].y);
    	        if (cnt < t[i].k) t[i].k -= cnt, tt1[++p1] = t[i]; else tt2[++p2] = t[i];
    	    }
        }
        for (rg int i = 1; i <= p2; ++i) if (tt2[i].id == 0) update(dfn[tt2[i].x], -tt2[i].k);
        for (rg int i = 1; i <= p1; ++i) t[ql + i - 1] = tt1[i];
        for (rg int i = 1; i <= p2; ++i) t[ql + p1 + i - 1] = tt2[i];
        solve(ql, ql + p1 - 1, l, mid), solve(ql + p1, qr, mid + 1, r);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        file("cpp");
    #endif
        read(n), read(m);
        for (rg int i = 1; i <= n; ++i) read(a[i]), t[++num] = (node) { 1, i, a[i], 0 };
        for (rg int u, v, i = 1; i < n; ++i) read(u), read(v), Add_edge(u, v), Add_edge(v, u);
        dfs(1, 0), dfs(1, 0, 1);
        for (rg int k, x, y, i = 1; i <= m; ++i) {
    	    read(k), read(x), read(y);
    	    if (k == 0) {
        	    t[++num] = (node) { -1, x, a[x], 0 };
    	        t[++num] = (node) { 1, x, a[x] = y, 0 };
    	    } else
        	    t[++num] = (node) { k, x, y, ++q };
        }
        solve(1, num, 0, 100000000);
        for (rg int i = 1; i <= q; ++i) if (ans[i] == 0) puts("invalid request!"); else printf("%d
    ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    1012 The Best Rank (25 分)(排序)
    1011. World Cup Betting (20)(查找元素)
    1009 Product of Polynomials (25 分)(模拟)
    1008 Elevator (20 分)(数学问题)
    1006 Sign In and Sign Out (25 分)(查找元素)
    1005 Spell It Right (20 分)(字符串处理)
    Kafka Connect 出现ERROR Failed to flush WorkerSourceTask{id=local-file-source-0}, timed out while wait
    flume、kafka、avro组成的消息系统
    Java23种设计模式总结【转载】
    Java编程 思维导图
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12246913.html
Copyright © 2011-2022 走看看