bzoj 3932 [CQOI2015]任务查询系统 (主席树)
版权声明:本文为博主原创文章,未经博主允许不得转载。
题意:
有一堆任务,每个任务都有一个起始时间和终止时间,外加一个优先级 。
查询第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 }