题目大意
实现一个查询系统。
每个任务用三元组(Si,Ei,Pi)描述表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。
我的做法
把p离散化。
按照离散化后的p建立可持久化线段树。
把一个任务拆成两个扔进线段树中。
查询时注意多个任务优先级相同的情况。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
struct tree
{
int l,r;
tree *ls,*rs;
int num;
ll sum;
tree()
{
l=r=num=0;
sum=0;
ls=rs=0;
}
};
tree *root[100010];
void mt(tree *&p)
{
if(p->l==p->r)
return;
p->num=p->ls->num+p->rs->num;
p->sum=p->ls->sum+p->rs->sum;
}
void build(tree *&p,int l,int r)
{
p=new tree;
p->l=l;
p->r=r;
if(l==r)
return;
int mid=(l+r)>>1;
build(p->ls,l,mid);
build(p->rs,mid+1,r);
}
void insert(tree *&p1,tree *&p2,int x,int v1,ll v2)
{
p2=new tree(*p1);
if(p2->l==p2->r)
{
p2->num+=v1;
p2->sum+=v2;
return;
}
int mid=(p2->l+p2->r)>>1;
if(x<=mid)
insert(p1->ls,p2->ls,x,v1,v2);
else
insert(p1->rs,p2->rs,x,v1,v2);
mt(p2);
}
ll query(tree *&p,int k)
{
if(k==0)
return 0;
if(p->l==p->r)
return p->sum/p->num*k;
if(k>=p->num)
return p->sum;
int mid=(p->l+p->r)>>1;
int s=p->ls->num;
if(k<=s)
return query(p->ls,k);
return p->ls->sum+query(p->rs,k-s);
}
struct p
{
int a,b,c;
ll d;
p(int a_=0,int b_=0,int c_=0,ll d_=0)
{
a=a_;
b=b_;
c=c_;
d=d_;
}
};
bool cmp(p a,p b)
{
return a.a<b.a;
}
p a[200010];
int d[100010];
int x[100010];
int y[100010];
int z[100010];
int main()
{
freopen("bzoj3932.in","r",stdin);
freopen("bzoj3932.out","w",stdout);
int n,m;
scanf("%d%d",&m,&n);
int i;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x[i],&y[i],&z[i]);
d[i]=z[i];
}
sort(d+1,d+m+1);
int tot=unique(d+1,d+m+1)-d-1;
for(i=1;i<=m;i++)
{
int t=lower_bound(d+1,d+tot+1,z[i])-d;
a[2*i-1]=p(x[i],t,1,z[i]);
a[2*i]=p(y[i]+1,t,-1,-z[i]);
}
build(root[0],1,tot);
sort(a+1,a+2*m+1,cmp);
for(i=1;i<=2*m;i++)
{
if(a[i].a>n)
break;
tree *now;
insert(root[a[i-1].a],now,a[i].b,a[i].c,a[i].d);
root[a[i].a]=now;
}
for(i=1;i<=n;i++)
if(!root[i])
root[i]=root[i-1];
ll pre=1;
for(i=1;i<=n;i++)
{
int X,A,B,C,K;
// scanf("%d%d%d%d",&X,&A,&B,&C);
// K=1+(A*pre+B)%C;
scanf("%d%d",&X,&K);
pre=query(root[X],K);
printf("%lld\n",pre);
}
return 0;
}