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

    【传送门:BZOJ3932


    简要题意:

      给出n个任务,每个任务给出开始时间和结束时间还有这个任务的优先度

      有m个询问,每个询问给出x和k,求第x秒的时候,优先度从小到大k个任务的优先度的和

      强制在线


    题解:

      主席树好题

      设c为这个子树有多少个任务,sum为这个子树里的权值和

      先把优先度离散化,然后插入主席树里

      因为主席树不能够在线区间修改,但是我们可以离线修改然后单点求值,用差分的方式来区间修改,然后将主席树合并得到前缀和

      然后单点查询就行了

      注意要用long long


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    struct node
    {
        int lc,rc;LL c,sum;
    }tr[5100000];int len,rt[210000];
    struct task
    {
        int l,r;LL p;
    }t[210000];
    bool cmp(task t1,task t2)
    {
        return t1.p<t2.p;
    }
    void add(int &u,int l,int r,int p,LL c,LL sum)
    {
        if(u==0) u=++len;
        tr[u].c+=c;tr[u].sum+=sum;
        if(l==r) return ;
        int lc=tr[u].lc,rc=tr[u].rc,mid=(l+r)/2;
        if(p<=mid) add(tr[u].lc,l,mid,p,c,sum);
        else add(tr[u].rc,mid+1,r,p,c,sum);
    }
    void merge(int &u1,int u2)
    {
        if(u1==0){u1=u2;return ;}
        if(u2==0) return ;
        tr[u1].c+=tr[u2].c;tr[u1].sum+=tr[u2].sum;
        merge(tr[u1].lc,tr[u2].lc);
        merge(tr[u1].rc,tr[u2].rc);
    }
    LL findans(int u,int l,int r,int p)
    {
        if(p>tr[u].c) return tr[u].sum;
        if(l==r) return LL(p)*tr[u].sum/tr[u].c;
        int lc=tr[u].lc,rc=tr[u].rc,mid=(l+r)/2;
        if(p<=tr[lc].c) return findans(lc,l,mid,p);
        else return findans(rc,mid+1,r,p-tr[lc].c)+tr[lc].sum;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d%d%lld",&t[i].l,&t[i].r,&t[i].p);
        sort(t+1,t+n+1,cmp);
        memset(rt,0,sizeof(rt));
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(t[i].p!=t[i-1].p) cnt++;
            add(rt[t[i].l],1,n,cnt,1,t[i].p);
            add(rt[t[i].r+1],1,n,cnt,-1,-t[i].p);
        }
        for(int i=2;i<=n;i++) merge(rt[i],rt[i-1]);
        LL pre=1;
        for(int i=1;i<=m;i++)
        {
            int x,a,b,c;
            scanf("%d%d%d%d",&x,&a,&b,&c);
            int k=1+(a*pre+b)%c;
            pre=findans(rt[x],1,n,k);
            printf("%lld
    ",pre);
        }
        return 0;
    }

     

  • 相关阅读:
    GAN 的推导、证明与实现。
    WGAN学习笔记
    常用损失函数积累
    交叉熵在loss函数中使用的理解
    贝叶斯决策
    极大似然估计
    gated pixelCNN。
    三叉搜索树 转载
    Rabin-Karp 字符串匹配算法
    面试题整理 转载
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8746994.html
Copyright © 2011-2022 走看看