zoukankan      html  css  js  c++  java
  • [JOISC2018]道路建设 LCT

    [JOISC2018]道路建设

    LOJ传送门

    考的时候打的大暴力,其实想到了LCT,但是思路有点没转过来。就算想到了估计也不能切,我没有在考场写LCT的自信。。。

    其实这题不是让你直接用LCT维护答案,只是借用了LCT的架构,让权值相同的点在同一棵splay中,用一棵splay顶端的点的权值表示这棵splay中所有点的权值。发现从根到某个点的操作跟LCT的access操作相似,可以把access操作魔改一下,一边splay、跳父亲,一边更新树状数组、统计答案。注意为了维护一棵splay的权值,rotate转到根的时候要更新根的权值。

    代码非常简短:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define R register
    #define I inline
    #define L long long
    #define B 1000000
    using namespace std;
    const int N = 100003;
    char buf[B], *p1, *p2;
    I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++; }
    I int rd() {
        R int f = 0;
        R char c = gc();
        while (c < 48 || c > 57)
            c = gc();
        while (c > 47 && c < 58)
            f = f * 10 + (c ^ 48), c = gc();
        return f;
    }
    L o;
    int a[N], c[N], b[N], v[N], n, t;
    struct T{int p, d[2], f, s;}e[N];
    I void mdf(int x, int k) {
        for (; x <= n; b[x] += k, x += x & -x)
            if (v[x] ^ t)
                v[x] = t, b[x] = 0;
    }
    I int qry(int x) {
        R int r = 0;
        for (; x; x ^= x & -x)
            if (v[x] == t)
                r += b[x];
        return r;
    }
    I int nrt(int x) { return e[e[x].p].d[0] == x || e[e[x].p].d[1] == x; }
    I void upd(int x) { e[x].s = e[e[x].d[0]].s + e[e[x].d[1]].s + 1; }
    I void rtt(int x) {
        R int f = e[x].p, g = e[f].p, b = e[f].d[0] == x, c = e[x].d[b];
        if (nrt(f))
            e[g].d[e[g].d[1] == f] = x;
        else
            e[x].f = e[f].f;
        if (c)
            e[c].p = f;
        e[x].p = g, e[f].p = x, e[x].d[b] = f, e[f].d[!b] = c, upd(f);
    }
    I void spl(int x) {
        R int f, g;
        for (;nrt(x); rtt(x)) {
            f = e[x].p, g = e[f].p;
            if (nrt(f))
                rtt((e[g].d[1] == f) ^ (e[f].d[1] == x) ? x : f);
        }
        upd(x);
    }
    I void acc(int x) {
        for (R int y = 0; x; x = e[y = x].p)
            spl(x), e[e[x].d[1]].f = e[x].f, o += 1ll * (e[e[x].d[0]].s + 1) * qry(e[x].f - 1), mdf(e[x].f, e[e[x].d[0]].s + 1), e[x].d[1] = y, upd(x);
    }
    int main() {
        R int i, x, y;
        n = rd();
        for (i = 1; i <= n; ++i)
            c[i] = rd(), a[i] = c[i];
        sort(a + 1, a + n + 1);
        for (i = 1; i <= n; ++i)
            e[i].f = lower_bound(a + 1, a + n + 1, c[i]) - a;
        for (i = 1; i < n; ++i)
            x = rd(), y = rd(), ++t, o = 0, acc(x), spl(x), e[x].p = y, e[y].d[0] = x, upd(y), printf("%I64d
    ", o);
        return 0;
    }
    
    

    换Windows了,%I64d就懒得改了。

  • 相关阅读:
    [置顶] 也论百度轻应用--一个开发者的吐槽
    HDU 1506 Largest Rectangle in a Histogram
    [置顶] 搭建apache+tomcat+memcached集群环境
    (step8.2.6)hdu 1848(Fibonacci again and again——组合博弈)
    SQL2005、2008、2000 清空删除日志
    网络获取北京时间和系统时间
    C++界面库
    Cocos2d-X游戏开发之Windows7+VS2010环境搭建(亲测)
    华为面试题——一道关于指针方面的编程题(C/C++)
    java之Math
  • 原文地址:https://www.cnblogs.com/cj-chd/p/10276991.html
Copyright © 2011-2022 走看看