zoukankan      html  css  js  c++  java
  • BZOJ 3932: [CQOI2015]任务查询系统

    http://www.lydsy.com/JudgeOnline/problem.php?id=3932

    主席树(可持久化线段树)模板题。

    然而我太了,调了1h+,发现询问区间前k大的时候,忘了对重复元素个数判断,导致WA。

    做法:把每个任务拆成两个事件,按照时间排序,从前往后建主席树。

    然后对每个询问查询区间前k大之和。

    贴个版子(指针):

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN=300005, MAXS=1e7+5;
    int M, N, tot, id[MAXN];
    int cnt[MAXN], num[MAXN];
    struct Node
    {
        Node *lc, *rc;
        int n, l, r;
        ll s;
        inline void up(){
            n=lc->n+rc->n;
            s=lc->s+rc->s;
        }
        ll qry(int k){
            if(l==r) return (ll)num[l]*min(k, n);
            if(k<=lc->n) return lc->qry(k);
            else return lc->s+rc->qry(k-lc->n);
        }
    }tr[MAXS], *rt[MAXN];
    void upd(Node *&c, Node *t, int x){
        c=&tr[tot++];
        c->l=t->l, c->r=t->r;
        if(c->l==c->r){
            c->n=cnt[x];
            c->s=(ll)cnt[x]*num[x];
            return;
        }
        int mid=(c->l+c->r)>>1;
        if(x<=mid){
            upd(c->lc, t->lc, x);
            c->rc=t->rc;
            c->up();
        }else{
            c->lc=t->lc;
            upd(c->rc, t->rc, x);
            c->up();
        }
    }
    void build(Node *&x, int l, int r)
    {
        x=&tr[tot++];
        x->l=l, x->r=r;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(x->lc, l, mid);
        build(x->rc, mid+1, r);
    }
    struct Evt{
        int x, t, p;
        bool operator<(const Evt &e) const {return x<e.x;}
    }E[MAXN];
    int main()
    {
        scanf("%d%d", &M, &N);
        for(int i=0; i<M; ++i){
            int s, e, p; scanf("%d%d%d", &s, &e, &p);
            E[i].x=s; E[i].t=1;
            E[i+M].x=e+1; E[i+M].t=0;
            E[i].p=E[i+M].p=p;
            num[i+1]=p;
        }
        sort(num+1, num+M+1); int nt=unique(num+1, num+M+1)-(num+1);
        for(int i=0; i<M; ++i){
            E[i].p=E[i+M].p=lower_bound(num+1, num+1+nt, E[i].p)-num;
        }
        M<<=1;
        sort(E, E+M); E[M++].x=N+1;
        build(rt[0], 1, nt);
        int last=0;
        for(int i=0; i<M; ++i){
            if(E[i].x>last){
                id[last]=i;
                last=E[i].x;
            }
            if(E[i].x>N) break;
            if(E[i].t) cnt[E[i].p]++;
            else cnt[E[i].p]--;
            upd(rt[i+1], rt[i], E[i].p);
        }
        for(int i=1; i<=N; ++i) if(!id[i]) id[i]=id[i-1];
        ll pre=1;
        for(int i=0; i<N; ++i){
            int x, a, b, c;
            scanf("%d%d%d%d", &x, &a, &b, &c);
            a=1+((ll)a*pre+b)%c;
            printf("%lld
    ", (pre=rt[id[x]]->qry(a)));
        }
        return 0;
    }
    
  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/will7101/p/6523370.html
Copyright © 2011-2022 走看看