• ZOJ 2112 Dynamic Rankings


    ZOJ_2112

        之前用线段树套平衡树写这个题目,现在发现那样写弱爆了……再次写这个题就是为了学习“主席树”,其实也就是可持久化数据结构的思想,思想来自于这篇博客:http://seter.is-programmer.com/posts/31907.html,写法来自于那个博主的代码:http://ideone.com/2Jp5W

        由于刚刚接触“主席树”就不再额外发表言论了。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXM 10010
    #define MAXD 60010
    #define LN 16
    struct Di
    {
        int id, v;
        bool operator < (const Di &t) const
        {
            return v < t.v;
        }
    }di[MAXD];
    struct List
    {
        int x, y, k;
    }list[MAXM];
    int N, M, S, rank[MAXD], node;
    struct SegTree
    {
        int ls, rs, size;
    }st[2560000]; // 尽量开大些...
    namespace ST
    {
        int build(int x = 0, int y = S)
        {
            int cur = ++ node, mid = x + y >> 1;
            st[cur].size = 0;
            if(x < y) st[cur].ls = build(x, mid), st[cur].rs = build(mid + 1, y);
            return cur;
        }
        int insert(int pre, int v, int d)
        {
            int t = ++ node, cur = t, x = 0, y = S;
            for(;;)
            {
                int mid = x + y >> 1;
                st[cur].size = st[pre].size + d;
                if(x == y) break;
                if(v <= mid)
                {
                    st[cur].rs = st[pre].rs, st[cur].ls = ++ node;
                    cur = node, pre = st[pre].ls, y = mid;
                }
                else
                {
                    st[cur].ls = st[pre].ls, st[cur].rs = ++ node;
                    cur = node, pre = st[pre].rs, x = mid + 1;
                }
            }
            return t;
        }
    }
    struct ChairTree
    {
        int T[20], n;
        ChairTree() : n(0){}
        ChairTree(int x) : n(1){T[0] = x;}
        operator int() const
        {
            int i, ans = 0;
            for(i = 0; i < n; i ++) ans += st[st[T[i]].ls].size;
            return ans;
        }
        void operator += (int x)
        {
            T[n ++] = x;
        }
        int operator ^= (int C)
        {
            for(int i = 0; i < n; i ++) T[i] = C ? st[T[i]].rs : st[T[i]].ls;
            return C;
        }
    };
    namespace BIT
    {
        int T[MAXD];
        void init()
        {
            T[1] = ST::build();
            for(int i = 2; i <= N; i ++) T[i] = T[1];
        }
        void insert(int x, int v, int d)
        {
            for(;x <= N; x += x & -x) T[x] = ST::insert(T[x], v, d);
        }
        void query(ChairTree &ct, int x)
        {
            for(; x > 0; x -= x & -x) ct += T[x];
        }
    }
    int A[MAXD];
    void init()
    {
        int i, n = 0;
        char op[5];
        scanf("%d%d", &N, &M);
        for(i = 1; i <= N; i ++) scanf("%d", &di[n].v), di[n].id = n + 1, ++ n;
        for(i = 0; i < M; i ++)
        {
            scanf("%s", op);
            if(op[0] == 'Q') scanf("%d%d%d", &list[i].x, &list[i].y, &list[i].k);
            else scanf("%d%d", &list[i].x, &di[n].v), list[i].k = -1, di[n].id = n + 1, ++ n;
        }
        std::sort(di, di + n);
        rank[di[0].id] = 0;
        for(i = 1, S = 0; i < n; i ++)
        {
            if(di[i].v != di[i - 1].v) di[++ S].v = di[i].v;
            rank[di[i].id] = S;
        }
        node = 0;
        BIT::init();
        for(A[0] = BIT::T[0], i = 1; i <= N; i ++)
            A[i] = ST::insert(A[i - 1], rank[i], 1);
    }
    void solve()
    {
        int i, n = N, C;
        for(i = 0; i < M; i ++)
        {
            if(list[i].k == -1)
            {
                BIT::insert(list[i].x, rank[list[i].x], -1);
                BIT::insert(list[i].x, rank[list[i].x] = rank[++ n], 1);
            }
            else
            {
                int x = 0, y = S, k = list[i].k;
                ChairTree a, b, c = A[list[i].y], d = A[list[i].x - 1];
                BIT::query(a, list[i].y), BIT::query(b, list[i].x - 1);
                for(;;)
                {
                    if(x == y) break;
                    int mid = x + y >> 1, t = a + c - b - d;
                    if(k <= t) a ^= b ^= c ^= d ^= 0, y = mid;
                    else k -= t, a ^= b ^= c ^= d ^= 1, x = mid + 1;
                }
                printf("%d\n", di[x].v);
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    android 3G移植【转】
    【转】小白级的CocoaPods安装和使用教程
    【转】Core Bluetooth框架之二:后台处理
    【转】Core Bluetooth框架之一:Central与Peripheral
    ios ble 参考
    拼音处理
    通过触发器实现数据库的即时同步
    数据库中存取文件
    交叉报表处理实例
    SQL Server 2005 中实现通用的异步触发器架构
  • 原文地址:https://www.cnblogs.com/staginner/p/2676040.html
Copyright © 2020-2023  润新知