码迷,mamicode.com
首页 > 其他好文 > 详细

[CTSC2008]网络管理

时间:2018-10-17 00:10:35      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:size   struct   ==   swa   stdout   pen   eof   没有   etc   

题面

题解

带修改的主席树???我可没有那么勤快去写个树套树

只要它不强制在线,我就可以用整体二分做

思路大致与【ZJOI2013】K大数查询相似

只不过放在树上做,还带修改

同样处理出询问,并且一个修改操作要拆分成两个

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x));

inline int read()
{
    int data = 0, w = 1;
    char ch = getchar();
    while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if(ch == '-') w = -1, ch = getchar();
    while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    return data*w;
}

const int maxn(80010);
struct edge { int next, to; } e[maxn << 1];
int head[maxn], e_num, n, q;
inline void add_edge(int from, int to) { e[++e_num] = (edge) {head[from], to}; head[from] = e_num; }
int pos[maxn], fa[maxn], size[maxn], heavy[maxn], belong[maxn], dep[maxn], cnt;

void dfs(int x)
{
    size[x] = 1;
    for(RG int i = head[x]; i; i = e[i].next)
    {
        int to = e[i].to; if(to == fa[x]) continue;
        fa[to] = x; dep[to] = dep[x] + 1; dfs(to);
        size[x] += size[to];
        if(size[heavy[x]] < size[to]) heavy[x] = to;
    }
}

void dfs(int x, int chain)
{
    pos[x] = ++cnt; belong[x] = chain;
    if(!heavy[x]) return;
    dfs(heavy[x], chain);
    for(RG int i = head[x]; i; i = e[i].next)
    {
        int to = e[i].to; if(to == fa[x] || to == heavy[x]) continue;
        dfs(to, to);
    }
}

int sum, ans[maxn], c[maxn], T[maxn];
struct qry { int k, a, b, id, opt; } p[maxn << 1], pl[maxn << 1], pr[maxn << 1];
inline void add(int x, int v) { while(x <= n) c[x] += v, x += x & -x; }
inline int query(int x) { int ans = 0; while(x) ans += c[x], x -= x & -x; return ans; }
inline int LCA(int a, int b)
{
    while(belong[a] ^ belong[b])
    {
        if(pos[belong[a]] < pos[belong[b]]) std::swap(a, b);
        a = fa[belong[a]];
    }
    return pos[a] < pos[b] ? a : b;
}

inline int Query(int a, int b)
{
    int ans = 0;
    while(belong[a] ^ belong[b])
    {
        if(pos[belong[a]] < pos[belong[b]]) std::swap(a, b);
        ans += query(pos[a]) - query(pos[belong[a]] - 1);
        a = fa[belong[a]];
    }
    if(pos[a] < pos[b]) std::swap(a, b);
    return ans + query(pos[a]) - query(pos[b] - 1);
}

void Div(int l, int r, int ql, int qr)
{
    if(ql > qr) return;
    if(l == r) { for(RG int i = ql; i <= qr; i++) if((!p[i].opt) && (~ans[p[i].id])) ans[p[i].id] = l; return; }

    int mid = (l + r) >> 1, tl = 0, tr = 0;
    for(RG int i = ql; i <= qr; i++)
    {
        if(p[i].k == 0)
            if(p[i].b <= mid) pl[++tl] = p[i];
            else pr[++tr] = p[i], add(pos[p[i].a], p[i].id);
        else
        {
            int sum = Query(p[i].a, p[i].b);
            if(sum >= p[i].k) pr[++tr] = p[i];
            else p[i].k -= sum, pl[++tl] = p[i];
        }
    }

    for(RG int i = ql; i <= qr; i++) if(p[i].opt && p[i].b > mid) add(pos[p[i].a], -p[i].id);
    for(RG int i = 1; i <= tl; i++) p[ql + i - 1] = pl[i];
    for(RG int i = 1; i <= tr; i++) p[ql + tl + i - 1] = pr[i];
    Div(l, mid, ql, ql + tl - 1); Div(mid + 1, r, ql + tl, qr);
}

int main()
{
#ifndef ONLINE_JUDGE
    file(cpp);
#endif

    n = read(); q = read(); int tot = 0;
    for(RG int i = 1; i <= n; i++) p[++tot] = (qry) {0, i, T[i] = read(), 1, 1};
    for(RG int i = 1, a, b; i < n; i++)
        a = read(), b = read(), add_edge(a, b), add_edge(b, a);
    dfs(1); dfs(1, 1);

    for(RG int i = 1, k, a, b; i <= q; i++)
    {
        k = read(); a = read(); b = read();
        if(k)
        {
            p[++tot] = (qry) {k, a, b, ++sum, 0};
            int dis = dep[a] + dep[b] - (dep[LCA(a, b)] << 1) + 1;
            if(p[tot].k > dis) ans[p[tot].id] = -1;
        }
        else p[++tot] = (qry) {0, a, T[a], -1, 1}, p[++tot] = (qry) {0, a, T[a] = b, 1, 1};
    }

    Div(1, 100000000, 1, tot);
    for(RG int i = 1; i <= sum; i++)
        (~ans[i]) ? printf("%d\n", ans[i]) : puts("invalid request!");
    return 0;
}

[CTSC2008]网络管理

标签:size   struct   ==   swa   stdout   pen   eof   没有   etc   

原文地址:https://www.cnblogs.com/cj-xxz/p/9800962.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!