BZOJ3932: [CQOI2015]任务查询系统

传送门

真不知道我没学主席树之前是有什么勇气说自己高级数据结构以及学的七七八八了。

这道题应该也是算是主席树的经典运用。

刚开始脑抽了,想把(S,E,P)的处理直接在线用树状数组xjb搞搞算了。写完后才意识到树状数组无法(很难?)实现区间修改。

然后想了想既然这个是一下子把所有修改都放上了直接用树状数组差分一下不就好了!

然后又深感自己制杖,为什么要用树状数组差分呢,直接开几个vector维护一下就行了。

说是修改,本质上是不带修改的主席树,很快搞完。WA,眼查,无果,跟踪,无果。

拍了几组小数组测了测,最后发现问题是这样的:以往的线段树在更新对应的权值线段树时只需要更新一个pos,而这个要更新很多个pos,就会导致一些层直接修改到以前的版本。

最后的解决办法就是对于每个点,开两个交叉更新即可。

语文不好QAQ,直接看代码比较清晰。

//BZOJ 3932
//by Cydiater
//2016.12.8
#include <iostream>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <algorithm>
#include <ctime>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
#define cmax(a,b)		a=max(a,b)
#define cmin(a,b)		a=min(a,b)
#define pii 			pair<int,int>
#define FILE "cqoi15_query"
const int MAXN=1e5+5;
const int oo=0x3f3f3f3f;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
	return x*f;
}
int N,M,fsort[MAXN],rnum=0,cnt=0,root[MAXN<<5];
ll Pre=1;
struct Query{
	int S,T,P;
}query[MAXN];
struct Chair_man_Tree{
	int tol,son[2];
	ll sum;
}t[MAXN<<6];
vector<pii> op[MAXN];
namespace solution{
	int NewNode(int tol,ll sum,int son0,int son1){
		t[++cnt].tol=tol;t[cnt].sum=sum;
		t[cnt].son[0]=son0;t[cnt].son[1]=son1;
		return cnt;
	}
	void insert(int leftt,int rightt,int &Root,int last,int pos,int flag){
		Root=NewNode(t[last].tol+flag,t[last].sum+fsort[pos]*flag,t[last].son[0],t[last].son[1]);
		if(leftt==rightt)		return;
		int mid=(leftt+rightt)>>1;
		if(pos<=mid)		insert(leftt,mid,t[Root].son[0],t[last].son[0],pos,flag);
		else 			insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos,flag);
	}
	void Build(){
		N=read();M=read();
		up(i,1,N){
			int S=read(),T=read(),P=read();
			fsort[++rnum]=P;
			query[i]=(Query){S,T,P};
		}
		sort(fsort+1,fsort+rnum+1);
		rnum=unique(fsort+1,fsort+rnum+1)-(fsort+1);
		up(i,1,N){
			int S=query[i].S,T=query[i].T,P=query[i].P,pos=lower_bound(fsort+1,fsort+rnum+1,P)-fsort;
			op[S].push_back(make_pair(pos,1));op[T+1].push_back(make_pair(pos,-1));
		}
		up(i,1,M){
			int last=root[i-1],now;
			up(j,0,(int)op[i].size()-1){
				pii tmp=op[i][j];
				int pos=tmp.first,flag=tmp.second;
				insert(1,rnum,now,last,pos,flag);
				last=now;
			}
			root[i]=last;
		}
	}
	ll Get(int leftt,int rightt,int Root,ll rnk){
		ll sum=t[Root].sum,tol=t[Root].tol;
		if(leftt==rightt)	return min(tol,rnk)*fsort[leftt];
		sum=t[t[Root].son[0]].sum;tol=t[t[Root].son[0]].tol;
		int mid=(leftt+rightt)>>1;
		if(rnk>=tol)	return sum+Get(mid+1,rightt,t[Root].son[1],rnk-tol);
		else 		return Get(leftt,mid,t[Root].son[0],rnk);
	}
	void Slove(){
		while(M--){
			ll X,A,B,C,K;
			X=read();A=read();B=read();C=read();
			K=1+(A*Pre+B)%C;
			printf("%lld\n",(Pre=Get(1,rnum,root[X],K)));
		}
	}
}
int main(){
	//freopen("input.in","r",stdin);
	//freopen("out1.out","w",stdout);
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	using namespace solution;
	Build();
	Slove();
	return 0;
}
时间: 2024-10-29 19:05:32

BZOJ3932: [CQOI2015]任务查询系统的相关文章

[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个 )的优先级之和是多少.特别的,如

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

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

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—任务查询系统

http://www.lydsy.com/JudgeOnline/problem.php?id=3932 (题目链接) 题意 给出$m$个区间,每个区间有一个权值,$n$组询问,每次询问在位置$x$权值前$k$大的区间的权值和. Solution 扫描线搞一下然后主席树维护即可. 细节 查询的时候注意叶子节的情况 代码 // bzoj3932 #include<algorithm> #include<iostream> #include<cstdlib> #includ

BZOJ3932:[CQOI2015]任务查询系统——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=3932 题面源于洛谷 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,

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

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

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

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

[CQOI2015]任务查询系统

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组\((S_i,E_i,P_i)\)描述,\((S_i,E_i,P_i)\)表示任务从第\(S_i\)秒开始,在第\(E_i\)秒后结束(第\(S_i\)秒和\(E_i\)秒任务也在运行),其优先级为\(P_i\).同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向查询系统询问,第\(X_i\)秒正在运行的任务中,优先级最小的\(K