zoukankan      html  css  js  c++  java
  • 【题解】CQOI2015任务查询系统

      主席树,操作上面基本上是一样的。每一个时间节点一棵树,一个树上的每个节点代表一个优先级的节点。把开始和结束时间点离散,在每一棵树上进行修改。注意因为一个时间节点可能会有多个修改,但我们要保证都在同一棵树上,所以我采取了让每个节点额外存储所属于的树的一个信息。当更新到一个节点的时候,如果属于建立好的新树,那么就修改;不属于,则重新建链。

      但这题有一个地方需要注意,就是所求的个数有可能小于一个叶子结点中存储的任务个数,这时我们就要返回k * num。

    代码(有的地方感觉自己写的有些啰嗦,大家看看就好):

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define maxn 1500000
    int n, m, timer, tot, cnt, sum, pre = 1, root[maxn], Ti[maxn];
    map <int, int> Map;
    bool vis[maxn];
    struct node
    {
        int t, num;
    }upd[maxn * 2];
    
    struct tree
    {
        int lson, rson, cal, root, size, rank;
    }T[maxn * 5];
    
    struct project
    {
        int s, e, p;
    }P[maxn];
    
    bool cmp(project a, project b)
    {
        return a.p < b.p;
    }
    
    bool cmp2(node a, node b)
    {
        return a.t < b.t;
    }
    
    int read()
    {
        int x = 0, k = 1;
        char c;
        c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    void update(int &now, int bf, int x, int num, int l, int r, int root)
    {
        if(root != T[now].root) now = ++ sum, T[now] = T[bf], T[now].root = root;
        if(num > 0) T[now].size += 1;
        else T[now].size -= 1;
        if(l == r)
        {
            T[now].cal += num;
            T[now].rank = num;
            return;
        }
        int mid = (l + r) >> 1;
        if(x <= mid) update(T[now].lson, T[bf].lson, x, num, l, mid, root);
        else update(T[now].rson, T[bf].rson, x, num, mid + 1, r, root);
        T[now].cal = T[T[now].lson].cal + T[T[now].rson].cal;
    }
    
    int query(int now, int L, int R, int k)
    {
        int mid = (L + R) >> 1;
        int size = T[T[now].lson].size;
        if(L == R) return k * T[now].rank;
        if(k >= T[now].size) return T[now].cal; 
        if(k <= size) return query(T[now].lson, L, mid, k);
        else return query(T[now].lson, L, mid, size) + query(T[now].rson, mid + 1, R, k - size);
    }
    
    signed main()
    {
        m = read(), n = read();
        for(int i = 1; i <= m; i ++)
        {
            P[i].s = read(), P[i].e = read(), P[i].p = read();
            upd[++ cnt] = (node) {P[i].s, P[i].p};
            upd[++ cnt] = (node) {P[i].e + 1, -P[i].p};
        }
        sort(P + 1, P + 1 + m, cmp);
        for(int i = 1; i <= m; i ++)
            if(P[i].p != P[i - 1].p) Map[P[i].p] = ++ tot;
        sort(upd + 1, upd + 1 + cnt, cmp2);
        for(int i = 1; i <= cnt; i ++) 
        {
            if(upd[i].t != upd[i - 1].t) 
            {
                int now = ++ timer; Ti[upd[i].t] = now;
                root[timer] = ++ sum;
                int t = upd[i].t - 1;
                while(!Ti[t]) Ti[t] = now - 1, t --;
            }
            int t = Ti[upd[i].t];
            update(root[t], root[t - 1], Map[abs(upd[i].num)], upd[i].num, 1, tot, t); 
            vis[t] = true;
        }
        for(int i = 1; i <= n; i ++)
        {
            int x = read(), a = read(), b = read(), c = read();
            int ans, k = 1 + (a * pre + b) % c;
            printf("%lld
    ", ans = query(root[Ti[x]], 1, tot, k));
            pre = ans;
        }
        return 0;
    }
  • 相关阅读:
    ZOJ 3818 Pretty Poem
    HDU 4597 Play Game
    HDU 4497 GCD and LCM
    CSU 1335 高桥和低桥
    UVA 10791 Minimum Sum LCM
    CSU 1119 Collecting Coins
    CSU 1120 病毒
    UVA 12169 Disgruntled Judge
    HDU 1301 Jungle Roads
    POJ 1258 Agri-Net
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/8525725.html
Copyright © 2011-2022 走看看