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 }
时间: 2024-10-12 04:29:33

bzoj 3932 [CQOI2015]任务查询系统 (主席树)的相关文章

BZOJ 3932: [CQOI2015]任务查询系统 | 主席树练习题

题目: 洛谷也能评测 题解: De了好长时间BUG发现是自己sort前面有一行for没删,气死. 题目询问第x秒时候前k小的P值之和. 朴素想法: 我们可以把P值离散化,然后对于每个时刻建一棵定义域是离散化后P值的线段树 每个节点维护了这个节点代表区间的任务个数和这些任务离散化之前的P值之和, 对于每个在这个时间段的任务,插入,即在p位置单点修改 询问就是类似二叉查找树的写法 高级想法: 首先把一段任务拆成两个:添加和删除,用三元组(t,p,d)表示,d=1表示插入,d=-1表示删除 对于第ma

BZOJ 3932 CQOI2015 任务查询系统 可持久化线段树

题目大意见http://pan.baidu.com/s/1o6zajc2 主席树裸上就好了... #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100100 using namespace std; struct Segtree{ Segtree *ls,*rs; int size; long long sum; void* op

bzoj 3932: [CQOI2015]任务查询系统

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

bzoj3932 [CQOI2015]任务查询系统——主席树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3932 第二道主席树!本来想自己手胡一下,但是还是写不下去了... 参考博客:https://www.cnblogs.com/CQzhangyu/p/6295579.html 就是对每个时间节点建一棵权值线段树,节点太多所以开成主席树: WA了好久,竟然是错在二分的地方了???看了半天还是不知道为什么错,那个写法已经用了好久了啊... 代码如下: #include<iostream> #i

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

现在有一群任务,每个任务都有开始和结束的时间和一个优先级,给你所有任务的开始结束时间和优先级,问你在某个时间点优先级最小的k个的优先级的和是多少. 普通的主席树是单点修改 区间查询   这题正好相反 可以用差分数组来做  区间查询改为1-i的前缀和 注意copy结点的方式 不能简单的复制T  还有son  t num 重复累加的操作  要写成T[i] T[i]      而不是  T[i-1] T[i] 主席树的范围只和放入的数据的离散化下标有关   和历史版本号没有任何关系 这题的时间为历史版

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

题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少.特别的,如果Ki大于第Xi秒正在

3932: [CQOI2015]任务查询系统

3932: [CQOI2015]任务查询系统 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2559  Solved: 819[Submit][Status][Discuss] Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为P

[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

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

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如