P3168 [CQOI2015]任务查询系统 主席树 差分数组

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans);
    
    return 0;
View Code

 

以上是关于P3168 [CQOI2015]任务查询系统 主席树 差分数组的主要内容,如果未能解决你的问题,请参考以下文章

P3168 [CQOI2015]任务查询系统

P3168 [CQOI2015]任务查询系统(主席树)

P3168 [CQOI2015]任务查询系统

P3168 [CQOI2015]任务查询系统 主席树 差分数组

luogu P3168 [CQOI2015] 任务查询系统

bzoj 3932 [CQOI2015]任务查询系统 (主席树)