3932: [CQOI2015]任务查询系统 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 3412 Solved: 1098 [Submit]

本文介绍了一道名为[CQOI2015]任务查询系统的算法题目,该题需要通过建立主席树来实现高效的时间任务查询。具体地,任务由开始时间、结束时间和优先级组成,系统需要查询特定时刻优先级最低的若干任务的优先级之和。
摘要由CSDN通过智能技术生成

3932: [CQOI2015]任务查询系统

Time Limit: 20 Sec   Memory Limit: 512 MB
Submit: 3412   Solved: 1098
[ Submit][ Status][ Discuss]

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

这道laji题,对拍对了我20h。
然后...........数组开小了。(我能怎么办,我也很绝望啊!)
题解:
以时间为下标,优先级为区间建主席树。
对于s1,e1,p1,
我们可以在s1时加上p1,e1+1时减去p1
维护区间和以及个数就好了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
const ll N=8000001;
const ll M=300010;
struct node{
	ll l,r,l1,r1,x;
	ll s;
}tr[N];ll tot=0,root[N];
ll m,n;
struct node1{
	ll s,p,x,k;
}sa[M];
struct node2{
	ll s,e,p,x;
}a[M];
bool cmp(node2 x,node2 y)
{
	return x.p<y.p;
}
void built(ll l,ll r)
{
	tot++;
	ll now=tot;
	tr[now].l=l;tr[now].r=r;
	if(l!=r)
	{
		ll mid=(l+r)>>1;
		tr[now].l1=tot+1;built(l,mid);
		tr[now].r1=tot+1;built(mid+1,r);
	}
}
inline ll ins(ll rt,ll l,ll r,ll p,ll x)
{
	if(rt==0) return 0;
	if(l<=tr[rt].l&&tr[rt].r<=r)
	{
		tot++;
		tr[tot].l=l;tr[tot].r=r;
		tr[tot].s=tr[rt].s+p*x;
		tr[tot].x=tr[rt].x+x;
		return tot;
	}
	else
	{
		//prllf("!");
		tot++;  
          ll pp=tot;  
          tr[pp].l=tr[rt].l;  
          tr[pp].r=tr[rt].r;  
          ll mid=(tr[rt].l+tr[rt].r)/2;  
          if(l<=mid)  
          {  
               tr[pp].l1=ins(tr[rt].l1,l,r,p,x);  
               tr[pp].r1=tr[rt].r1;  
          }  
          if(r>mid)  
          {  
               tr[pp].l1=tr[rt].l1;  
               tr[pp].r1=ins(tr[rt].r1,l,r,p,x);  
          }  
          tr[pp].s=tr[tr[pp].l1].s+tr[tr[pp].r1].s;  
          tr[pp].x=tr[tr[pp].l1].x+tr[tr[pp].r1].x;  
          return pp;  
	}
}
long long f[100001],fx[100001];  
ll getans(ll rt,ll k)
{
      if(tr[rt].l==tr[rt].r)
	  {
	  	return f[tr[rt].l]*k;  
	  }	
	  if(tr[rt].x<=k)
	  return tr[rt].s;
	  if(tr[tr[rt].l1].x<k)
	  return tr[tr[rt].l1].s+getans(tr[rt].r1,k-tr[tr[rt].l1].x);
	  return getans(tr[rt].l1,k);
}

bool cmp2(node1 x,node1 y)
{
	 return x.s<y.s;
}
int main()
{
	scanf("%lld%lld",&m,&n);
	ll s1,e1,p1;
	for(ll i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&a[i].s,&a[i].e,&a[i].p);
		a[i].x=i;
		
	}
	
	sort(a+1,a+1+m,cmp);
	ll p=0;  
    p++;  
    f[p]=a[1].p;  
    fx[a[1].x]=p;  
    for(ll i=2;i<=m;i++)  
     {  
          if(a[i].p!=a[i-1].p)  
          {  
               p++;  
               f[p]=a[i].p;  
          }  
          fx[a[i].x]=p;  
     }  
	ll tx=0;
	for(ll i=1;i<=m;i++)
	{
		tx++;
		sa[tx].s=a[i].s;
		sa[tx].p=a[i].p;
		sa[tx].x=1;
		sa[tx].k=fx[a[i].x];  
		tx++;
		sa[tx].s=a[i].e+1;
		sa[tx].p=a[i].p;
		sa[tx].x=-1;
		sa[tx].k=fx[a[i].x];  
	}
	sort(sa+1,sa+1+tx,cmp2);
	root[0]=tot+1;
	built(1,p);
	ll lar=root[0];
	for(ll i=1;i<=tx;i++)
	{
		ll tp=tot+1;
		ll yu=ins(lar,sa[i].k,sa[i].k,sa[i].p,sa[i].x);
		
		root[sa[i].s]=tp;
		lar=tp;
	}
	for(int i=1;i<=sa[tx].s;i++)  
          if(root[i]==0)  
               root[i]=root[i-1];  
	ll x1,a1,b1,c1,k1;
	long long pre=1;
	for(ll i=1;i<=n;i++)
	{
		scanf("%lld%lld%lld%lld",&x1,&a1,&b1,&c1);
		k1=1+(a1*pre+b1)%c1;
		pre=getans(root[x1],k1);
		printf("%lld\n",pre);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值