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* operator new (size_t,Segtree *_,Segtree *__,int ___,long long ____)
	{
		#define L (1<<15)
		static Segtree *mempool,*C;
		if(C==mempool)
			mempool=(C=new Segtree[L])+L;
		C->ls=_;
		C->rs=__;
		C->size=___;
		C->sum=____;
		return C++;
	}
	friend Segtree* Build_Tree(Segtree *p,int x,int y,int pos,int d_size,long long d_sum)
	{
		int mid=x+y>>1;
		if(x==y)
			return new (0x0,0x0,p->size+d_size,p->sum+d_sum)Segtree;
		if(pos<=mid)
			return new (Build_Tree(p->ls,x,mid,pos,d_size,d_sum),p->rs,p->size+d_size,p->sum+d_sum)Segtree;
		else
			return new (p->ls,Build_Tree(p->rs,mid+1,y,pos,d_size,d_sum),p->size+d_size,p->sum+d_sum)Segtree;
	}
	friend long long Query(Segtree *p,int x,int y,int k)
	{
		int mid=x+y>>1;
		if(x==y)
			return (long long)mid*min(k,p->size);
		if(k<=p->ls->size)
			return Query(p->ls,x,mid,k);
		else
			return Query(p->rs,mid+1,y,k-p->ls->size) + p->ls->sum ;
	}
}*tree[M];

struct abcd{
	bool flag;
	int tim,val;
	bool operator < (const abcd &a) const
	{
		return tim < a.tim ;
	}
}a[M<<1];

int n,m;
long long last_ans=1;

int main()
{
	int i,j,x,y,z,A,B,C;
	cin>>m>>n;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		a[i+i-1].flag=true;
		a[i+i-1].tim=x;
		a[i+i-1].val=z;
		a[i<<1].flag=false;
		a[i<<1].tim=y+1;
		a[i<<1].val=z;
	}
	sort(a+1,a+m+m+1);
	tree[0]=new (0x0,0x0,0,0ll)Segtree;
	tree[0]->ls=tree[0]->rs=tree[0];
	for(j=1,i=1;i<=n;i++)
	{
		tree[i]=tree[i-1];
		for(;j<=m<<1&&a[j].tim==i;j++)
			tree[i]=Build_Tree(tree[i],1,10000000,a[j].val,a[j].flag?1:-1,a[j].val*(a[j].flag?1:-1));
	}
	for(i=1;i<=n;i++)
	{
		scanf("%d%d%d%d",&x,&A,&B,&C);
		int k=(A*last_ans+B)%C+1;
		printf("%lld\n",last_ans=Query(tree[x],1,10000000,k));
	}
	return 0;
}
时间: 2024-10-11 01:10:30

BZOJ 3932 CQOI2015 任务查询系统 可持久化线段树的相关文章

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

题目大意 给出一些任务开始的时间,结束的时间,和优先级.问在第k秒时的第k大优先级,和前k小优先级的和. 思路 CQOI太良心,所有题都是512M. 这个题只需要按照时间轴弄一个可持久化线段树就行了,每个时间点对应着一个权值线段树,维护子节点的和和个数. 注意在没有操作的时候,当前时间点的线段树要复制上一个时间点的线段树. CODE #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #inclu

【BZOJ3932】【CQOI2015】任务查询系统 可持久化线段树

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44937681"); } 题解: 首先肯定要用线段树. 如果没有强制在线,那么直接把询问排个序然后按秩插入.删除.查询.普通线段树就好了,但是这道题强制在线,就需要可持久化线段树了. 线段树的每个区间记录[x:这段区间有的权值总和].

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

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载. bzoj 3832 题意: 有一堆任务,每个任务都有一个起始时间和终止时间,外加一个优先级 . 查询第xi秒优先级最小的k任务的优先级的和,如果第xi秒任务数小于k,则输出所有任务的优先级的和 . 解法: 每一秒都建立一颗线段树,线段树记录该时间点每个优先级出现的次数 . 可以把每个任务拆成两部分,一个在某个时间点该优先级次数加1,另一个就是减1了,然后按时间排序,随意搞搞就行了 . code 1 #include <iostream> 2

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

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

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

BZOJ 3123 SDOI 2013 森林 可持久化线段树+启发式合并

题目大意:给出一个森林,每个节点都有一个权值.有若干加边操作,问两点之间路径上的第k小权值是多少. 思路:这题和COT1比较像,但是多了连接操作.这样就只能暴力合并连个树.启发式合并会保证时间复杂度不至于太大.然后就是用可持久化线段树维护一个树的信息,按照dfs序来建树,每个节点的可持久化链的参考版本就是它父亲的版本.之后利用权值线段树可区间加减的特性,用f[x] + f[y] - f[lca] - f[father[lca]]来计算权值. CODE: #include <cstdio> #i

BZOJ 2653 middle 二分答案+可持久化线段树

题目大意:给定一个长度为n的序列,求当子序列s的左端点在[a,b],右端点在[c,d]时的最大中位数 其中当序列长度为偶数时中位数定义为中间两个数中较大的那个 很难想的一道题 具体题解见 http://blog.csdn.net/acm_cxlove/article/details/8566093 说的很详细 区间处理那里 [b,c]是必选的 [a,b)和(c,d]每段取最大加和 否则re恒>=0 #include<cstdio> #include<cstring> #inc

[BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】

题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更简单的做法,但是我没有什么想法... 代码 #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #inclu