BZOJ 3932 [CQOI2015]任务查询系统

来源:互联网 发布:js绑定事件的方法区别 编辑:程序博客网 时间:2024/06/07 07:27
BZOJ 3932 [CQOI2015]任务查询系统


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


输入输出格式
输入格式:
输入文件第一行包含两个空格分开的正整数m和n,分别表示任务总数和时间范围。接下来m行,每行包含三个空格分开的正整数Si、Ei和Pi(Si<=Ei),描述一个任务。接下来n行,每行包含四个空格分开的整数Xi、Ai、Bi和Ci,描述一次查询。查询的参数Ki需要由公式 Ki=1+(Ai*Pre+Bi) mod Ci计算得到。其中Pre表示上一次查询的结果,对于第一次查询,Pre=1。


输出格式:
输出共n行,每行一个整数,表示查询结果。


输入输出样例
输入样例#1: 复制
4 3
1 2 6
2 3 3
1 3 2
3 3 4
3 1 3 2
1 1 3 4
2 2 4 3
输出样例#1: 复制
2
8
11
说明
样例解释


K1 = (1*1+3)%2+1 = 1


K2 = (1*2+3)%4+1 = 2


K3 = (2*8+4)%3+1 = 3


对于100%的数据,1<=m,n,Si,Ei,Ci<=100000,0<=Ai,Bi<=100000,1<=Pi<=10000000,Xi为1到n的一个排列


区间修改很烦。
于是就利用主席树前缀和的性质差分。
可能忘掉如果没有修改操作也要将Root[I]=Root[I-1];
同时可以利用版本标记Mark[]来记录某节点的版本,从而在获得其上一个版本的信息的同时也能够修改此版本的信息。现在是每个时间点至多新建logn个点,否则就要每单个修改就要新建logn个点。


#include <iostream>#include <cstdio>#include <algorithm>using namespace std;typedef long long LL;inline LL Read(){LL X=0,F=1;char Ch=getchar();while(Ch<'0'||Ch>'9'){if(Ch=='-')F=-1;Ch=getchar();}while(Ch>='0'&&Ch<='9'){X=X*10+Ch-'0';Ch=getchar();}return X*F;}const int MAXN=1e5+5,MAXVAL=1e7;struct Op{int X,Val,Kind;bool operator < (const Op &B)const{return X<B.X;}}A[MAXN<<1];int Cnt[MAXN*60],Ls[MAXN*60],Rs[MAXN*60],N,M,QPos,Val,Kind,Ver,Tot,Mark[MAXN*60],Sz,Root[MAXN];LL Sum[MAXN*60];void Update(int X,int &Y,int L,int R){if(Mark[Y]!=Ver){Y=++Sz;Mark[Y]=Ver;Cnt[Y]=Cnt[X],Sum[Y]=Sum[X];Ls[Y]=Ls[X],Rs[Y]=Rs[X];}Cnt[Y]+=Val,Sum[Y]+=(LL)QPos*Val;if(L==R)return;int Mid=(L+R)>>1;if(QPos<=Mid)Update(Ls[X],Ls[Y],L,Mid);else Update(Rs[X],Rs[Y],Mid+1,R);}LL Query(int I,int L,int R){if(L==R)return (LL)QPos*L;int Mid=(L+R)>>1;if(QPos<=Cnt[Ls[I]])return Query(Ls[I],L,Mid);else {QPos-=Cnt[Ls[I]];return Query(Rs[I],Mid+1,R)+Sum[Ls[I]];}}int main(){N=Read(),M=Read();for(int I=1,L,R,K;I<=N;++I){L=Read(),R=Read(),K=Read();A[++Tot].X=L,A[Tot].Val=K,A[Tot].Kind=1;if(R==M)continue;A[++Tot].X=R+1,A[Tot].Val=K,A[Tot].Kind=-1;}sort(A+1,A+Tot+1);for(int I=1;I<=Tot;++I){if(A[I].X-A[I-1].X>1){for(int J=A[I-1].X;J<A[I].X;++J)Root[J+1]=Root[J];}Ver=A[I].X;QPos=A[I].Val,Val=A[I].Kind;Update(Root[Ver-1],Root[Ver],1,MAXVAL);}for(int I=Ver;I<M;++I)Root[I+1]=Root[I];LL Pre=1,A,B,C,K;for(int I=1,X;I<=M;++I){X=Read(),A=Read(),B=Read(),C=Read();K=1+(A*Pre+B)%C;if(K>=Cnt[Root[X]])printf("%lld\n",Pre=Sum[Root[X]]);else QPos=K,printf("%lld\n",Pre=Query(Root[X],1,MAXVAL));}return 0;}