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

版权声明:本文为博主原创文章,未经博主允许不得转载。

bzoj 3832

题意:

  有一堆任务,每个任务都有一个起始时间和终止时间,外加一个优先级 。

  查询第xi秒优先级最小的k任务的优先级的和,如果第xi秒任务数小于k,则输出所有任务的优先级的和 。

解法:

  每一秒都建立一颗线段树,线段树记录该时间点每个优先级出现的次数 。

  可以把每个任务拆成两部分,一个在某个时间点该优先级次数加1,另一个就是减1了,然后按时间排序,随意搞搞就行了 。

 

code

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <queue>
  7 #include <set>
  8 #include <vector>
  9 #include <map>
 10 #define ll long long
 11 
 12 using namespace std;
 13 
 14 const int N=1e5+7;
 15 
 16 struct node{
 17     int t,p;
 18     bool f;
 19     bool operator < (const node & x) const {
 20         return t<x.t;
 21     }
 22 }a[N*2];
 23 
 24 int sorted[N];
 25 int m,n;
 26 
 27 int Ls[N*40],Rs[N*40],cnt[N*40];
 28 ll sum[N*40];
 29 int root[N],tot;
 30 
 31 inline int Hash(int x){
 32     return lower_bound(sorted+1,sorted+n+1,x)-sorted;
 33 }
 34 
 35 inline int bulidtree(int L,int R){
 36     int k=tot++;
 37     cnt[k]=sum[k]=0;
 38     if (L==R) return k;
 39     int mid=(L+R)>>1;
 40     Ls[k]=bulidtree(L,mid);
 41     Rs[k]=bulidtree(mid+1,R);
 42     return k;
 43 }
 44 
 45 inline void copy(int x,int y){
 46     Ls[x]=Ls[y];
 47     Rs[x]=Rs[y];
 48     cnt[x]=cnt[y];
 49     sum[x]=sum[y];
 50 }
 51 
 52 inline int update(int o,int p,int x,int L,int R){
 53     int k=tot++;
 54     copy(k,o);
 55     cnt[k]+=x;
 56     sum[k]+=x*sorted[p];
 57     if (L==R) return k;
 58     int mid=(L+R)>>1;
 59     if (p<=mid) Ls[k]=update(Ls[k],p,x,L,mid);
 60     else Rs[k]=update(Rs[k],p,x,mid+1,R);
 61     return k;
 62 }
 63 
 64 inline ll query_sum(int o,int k,int L,int R){
 65     if (k>=cnt[o]) return sum[o];
 66     if (L==R) return sum[o]/cnt[o]*k;
 67     int res=cnt[Ls[o]];
 68     int mid=(L+R)>>1;
 69     if (k<=res) return query_sum(Ls[o],k,L,mid);
 70     else return sum[Ls[o]]+query_sum(Rs[o],k-res,mid+1,R);
 71 }
 72 
 73 int main(){
 74     scanf("%d%d",&m,&n);
 75     for (int i=1;i<=m;i++){
 76         int S,E,P;
 77         scanf("%d%d%d",&S,&E,&P);
 78         a[i*2-1].t=S; a[i*2-1].p=P; a[i*2-1].f=true;
 79         a[i*2].t=E+1; a[i*2].p=P; a[i*2].f=false;
 80         sorted[i]=P;
 81     }
 82 
 83     sort(a+1,a+1+2*n);
 84     sort(sorted+1,sorted+n+1);
 85 
 86     root[0]=bulidtree(1,n);
 87     int j=1;
 88     for (int i=1;i<=n;i++) {
 89         root[i]=root[i-1];
 90         while (j<=2*n && a[j].t==i){
 91             if (a[j].f) 
 92                 root[i]=update(root[i],Hash(a[j].p),1,1,n);
 93             else 
 94                 root[i]=update(root[i],Hash(a[j].p),-1,1,n);
 95             j++;
 96         }
 97     }
 98 
 99     ll pre=1;
100     int X,A,B,C,K;
101     for (int i=1;i<=n;i++){
102         scanf("%d %d %d %d",&X,&A,&B,&C);
103         K=1+(A*pre+B)%C;
104         pre=query_sum(root[X],K,1,n);
105         printf("%lld\n",pre);
106     }
107     return 0;
108 }

 

posted @ 2016-10-18 22:57  without_ACM  阅读(225)  评论(0编辑  收藏  举报