zoukankan      html  css  js  c++  java
  • P3168 [CQOI2015]任务查询系统 主席树 差分数组

      现在有一群任务,每个任务都有开始和结束的时间和一个优先级,给你所有任务的开始结束时间和优先级,问你在某个时间点优先级最小的k个的优先级的和是多少.

    普通的主席树是单点修改 区间查询   这题正好相反

    可以用差分数组来做  区间查询改为1-i的前缀和 

    注意copy结点的方式 不能简单的复制T  还有son  t num  

    重复累加的操作  要写成T[i] T[i]      而不是  T[i-1] T[i]  

    主席树的范围只和放入的数据的离散化下标有关   和历史版本号没有任何关系  

    这题的时间为历史版本号  和主席树的范围没有关系

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    int son[N<<5][2];
    ll t[N<<5],num[N<<5];
    int T[N<<5],ncnt;
    
    struct node {int x,v;ll flag; } a[N];
    int n,m;
    ll b[N];
    void build(int l,int r,int &pos)
    {
        pos=++ncnt;
        if(l==r)return ;
        int m=l+r>>1;
        build(l,m,son[pos][0]);
        build(m+1,r,son[pos][1]);
    }
    void up(int x,int flag,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;
        son[pos][0]=son[pre][0];
        son[pos][1]=son[pre][1];
        t[pos]=t[pre]+flag*b[x];
        num[pos]=num[pre]+flag;
        
        if(l==r){return ;}
        int m=l+r>>1;
        if(x<=m)up(x,flag,l,m,son[pos][0],son[pos][0]);
        else up(x,flag,m+1,r,son[pos][1],son[pos][1]);
    }
    
    int qsum(int k,int l,int r,int pos)
    {
        if(l==r)return min(k*t[pos]/num[pos],t[pos]);
        if(num[pos]<=k)return t[pos];
        int m=l+r>>1;
        if(num[son[pos][0]]>=k)return qsum(k,l,m,son[pos][0]);
        else return t[son[pos][0]]+qsum(k-num[son[pos][0]],m+1,r,son[pos][1]);
    }
    void cpy(int &pos,int pre)
    {
        pos=++ncnt;
        son[pos][0]=son[pre][0];
        son[pos][1]=son[pre][1];
        t[pos]=t[pre];
        num[pos]=num[pre];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        rep(i,1,n)
        {
            int x,y;ll z;scanf("%d%d%lld",&x,&y,&z);
            a[2*i-1]=(node){x,z,1};
            a[2*i  ]=(node){y+1,z,-1};
            b[i]=z;
        }
        sort(b+1,b+1+n);
        int nn=unique(b+1,b+1+n)-b-1;
        sort(a+1,a+1+2*n,[](node a,node b){return a.x<b.x;}  );
        build(1,nn,T[0]);
        
        int pos=1;
        rep(i,1,m)
        {
            cpy(T[i],T[i-1]);
            while(pos<=2*n&&a[pos].x==i)
            {
                up(lower_bound(b+1,b+1+nn,a[pos].v)-b,a[pos].flag,1,nn,T[i],T[i]); pos++;//注意这里如果写成T[i-1],T[i]  就不能满足重复更新
            }
        }
        ll ans=1,A,B,C,x,k;
        rep(j,1,m)
        {
            scanf("%lld%lld%lld%lld",&x,&A,&B,&C);
            k=1+(A*ans+B)%C;
            if(k>=num[T[x]]) ans=t[T[x]];
            else
            ans=qsum((int)k,1,nn,T[x]);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2、容器初探
    3、二叉树:先序,中序,后序循环遍历详解
    Hebbian Learning Rule
    论文笔记 Weakly-Supervised Spatial Context Networks
    在Caffe添加Python layer详细步骤
    论文笔记 Learning to Compare Image Patches via Convolutional Neural Networks
    Deconvolution 反卷积理解
    论文笔记 Feature Pyramid Networks for Object Detection
    Caffe2 初识
    论文笔记 Densely Connected Convolutional Networks
  • 原文地址:https://www.cnblogs.com/bxd123/p/11281463.html
Copyright © 2011-2022 走看看