【BZOJ3932】任务查询系统(主席树)

【BZOJ3923】任务查询系统(主席树)

题面

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

2

8

11

HINT

样例解释

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的一个排列

题解

真是一道好题
对于一个任务出现的时间
拆为:S时刻出现,E+1时刻消失
那么,以优先级为权值,构建主席树
把任务拆开后,很容易利用主席树求前缀和
所以第K大也就很容易的求出来了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 120000
#define ll long long
inline int read()
{
	int x=0,t=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=-1,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return x*t;
}
struct Event
{
	int t,p,w;
}e[MAX<<2];
struct Node
{
	int ls,rs;
	int v;
	long long s;
}t[MAX<<5];
int n,m,tot,sum,S[MAX],cnt,rt[MAX];
bool operator<(Event a,Event b){return a.t<b.t;}
void Build(int &now,int l,int r)
{
	now=++tot;
	if(l==r)return;
	int mid=(l+r)>>1;
	Build(t[now].ls,l,mid);
	Build(t[now].rs,mid+1,r);
}
void Modify(int &now,int ff,int l,int r,int pos,int w)
{
	now=++tot;
	t[now]=t[ff];t[now].v+=w;t[now].s+=S[pos]*w;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(pos<=mid)Modify(t[now].ls,t[ff].ls,l,mid,pos,w);
	else Modify(t[now].rs,t[ff].rs,mid+1,r,pos,w);
}
ll Query(int now,int l,int r,int k)
{
	if(t[now].v<=k)return t[now].s;
	if(l==r)return t[now].s/(1ll*t[now].v)*1ll*k;
	int mid=(l+r)>>1;
	if(k<=t[t[now].ls].v)return Query(t[now].ls,l,mid,k);
	else return t[t[now].ls].s+Query(t[now].rs,mid+1,r,k-t[t[now].ls].v);
}
int main()
{
	m=read();n=read();
	for(int i=1;i<=m;++i)
	{
		cnt++;
		e[cnt].t=read();e[cnt+1].t=read()+1;
		S[++sum]=e[cnt].p=e[cnt+1].p=read();
		e[cnt].w=1;e[cnt+1].w=-1;
		cnt++;
	}
	sort(&S[1],&S[sum+1]);
	sum=unique(&S[1],&S[sum+1])-S-1;
	sort(&e[1],&e[cnt+1]);
	Build(rt[0],1,sum);
	for(int i=1;i<=cnt;++i)
	{
		int pp=lower_bound(&S[1],&S[sum+1],e[i].p)-S;
		Modify(rt[e[i].t],rt[e[i-1].t],1,sum,pp,e[i].w);
	}
	for(int i=1;i<=n;++i)
		if(!rt[i])rt[i]=rt[i-1];
	ll ls=1;
	while(n--)
	{
		int X=read(),A=read(),B=read(),C=read();
		int K=1+(1ll*A*ls%C+B)%C;
		printf("%lld\n",ls=Query(rt[X],1,sum,K));
	}
	return 0;
}

posted @ 2017-12-27 16:13  小蒟蒻yyb  阅读(371)  评论(0编辑  收藏  举报