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

题目大意:有n个任务,有起始时间si和结束时间ei,以及该任务重要度pi,求某时刻xi正在进行的任务中,重要度前ki小任务的重要度之和

本以为是一道主席树的水题,可我调了半个多小时才调出来,原来是我新建的主席树根的左右儿子并没继承上个版本,导致某些时刻并没有任何刚开始或刚结束的任务,而在这个时间却找不到这个时刻对应的主席树。

然而我只有80分

看了题解,发现我忽略了一种情况,当很多个任务重要度相同时,可能前ki小个任务并不能把这些任务都取到,特判即可

  1 #include <cstdio>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #define N 100100
  6 #define ui unsigned int 
  7 #define il inline
  8 #define ll long long 
  9 #define rint register int
 10 using namespace std;
 11 
 12 int n,m,ctt,ma,tot;
 13 int root[N];
 14 ll a[N];
 15 struct Seg{int ls,rs;ll sum,sz;}seg[N*50];
 16 vector<ll>S[N];
 17 vector<ll>E[N];
 18 
 19 int gc(){
 20     int rett=0,fh=1;char p=getchar();
 21     while(p<'0'||p>'9') {if(p=='-')fh=-1;p=getchar();}
 22     while(p>='0'&&p<='9') {rett=(rett<<3)+(rett<<1)+p-'0';p=getchar();}
 23     return rett*fh;
 24 }
 25 void build(int l,int r,int rt)
 26 {
 27     if(l==r) return;
 28     int mid=(l+r)>>1;
 29     seg[rt].ls=++tot,build(l,mid,seg[rt].ls);
 30     seg[rt].rs=++tot,build(mid+1,r,seg[rt].rs);
 31 }
 32 il void pushup(int rt)
 33 {seg[rt].sum=seg[seg[rt].ls].sum+seg[seg[rt].rs].sum;
 34  seg[rt].sz=seg[seg[rt].ls].sz+seg[seg[rt].rs].sz;}
 35 void update(int x,int l,int r,int rt1,int rt2,ll val)
 36 {
 37     if(l==r) {seg[rt2].sz+=val,seg[rt2].sum+=val*a[l];return;}
 38     int mid=(l+r)>>1;
 39     if(x<=mid){
 40         if(!seg[rt2].ls||seg[rt2].ls==seg[rt1].ls){
 41             seg[rt2].ls=++tot,seg[seg[rt2].ls].sz=seg[seg[rt1].ls].sz;
 42             seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum;
 43             if(!seg[rt2].rs) seg[rt2].rs=seg[rt1].rs;
 44         }update(x,l,mid,seg[rt1].ls,seg[rt2].ls,val);
 45     }else{
 46         if(!seg[rt2].rs||seg[rt2].rs==seg[rt1].rs){
 47             seg[rt2].rs=++tot,seg[seg[rt2].rs].sz=seg[seg[rt1].rs].sz;
 48             seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum;
 49             if(!seg[rt2].ls) seg[rt2].ls=seg[rt1].ls;
 50         }update(x,mid+1,r,seg[rt1].rs,seg[rt2].rs,val);
 51     }pushup(rt2);
 52 }
 53 ll query(ll w,int l,int r,int rt)
 54 {
 55     if(l==r){
 56         if(w<seg[rt].sz) return (ll)a[l]*w;
 57         else return seg[rt].sum;  
 58     } 
 59     int mid=(l+r)>>1;
 60     if(seg[seg[rt].ls].sz>=w) return query(w,l,mid,seg[rt].ls);
 61     else return seg[seg[rt].ls].sum+query(w-seg[seg[rt].ls].sz,mid+1,r,seg[rt].rs);
 62 }
 63 
 64 int main()
 65 {
 66     scanf("%d%d",&m,&n);
 67     int x,y,w;ll z;
 68     for(int i=1;i<=m;i++){
 69         x=gc(),y=gc(),z=gc();
 70         a[++ctt]=z,S[x].push_back(z),E[y+1].push_back(z);
 71     }
 72     sort(a+1,a+ctt+1);
 73     ma=unique(a+1,a+ctt+1)-(a+1);
 74     a[ma+1]=0x3f3f3f3f;
 75     root[0]=++tot,build(1,ma,root[0]);
 76     for(int i=1;i<=n;i++){
 77         root[i]=++tot;
 78         seg[root[i]].ls=seg[root[i-1]].ls;
 79         seg[root[i]].rs=seg[root[i-1]].rs;
 80         seg[root[i]].sz=seg[root[i-1]].sz;
 81         seg[root[i]].sum=seg[root[i-1]].sum;
 82         for(int j=0;j<S[i].size();j++){
 83             int pos=lower_bound(a+1,a+ma+1,S[i][j])-a;
 84             update(pos,1,ma,root[i-1],root[i],(ll)1);
 85         }
 86         for(int j=0;j<E[i].size();j++){
 87             int pos=lower_bound(a+1,a+ma+1,E[i][j])-a;
 88             update(pos,1,ma,root[i-1],root[i],(ll)-1);
 89         }
 90     }
 91     ll ans=1;
 92     ll s1,s2,s3;
 93     for(int i=1;i<=n;i++){
 94         x=gc(),s1=gc(),s2=gc(),s3=gc();
 95         s1=(s1*ans+s2)%s3+1ll;
 96         ans=query(s1,1,ma,root[x]);
 97         printf("%lld\n",ans);
 98     }
 99     return 0;
100 }

 

posted @ 2018-09-24 22:29  guapisolo  阅读(140)  评论(0编辑  收藏  举报