题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3932
题解
将每个进程拆成两个操作:开始进程和结束进程,离散化优先级,然后按时间排序。
建一棵主席树,区间为离散化的优先级大小,每一个时间建一个根。
对于每一个操作,令时间为,优先级为,如果当前时间没有过操作,那么就在的基础上修改,否则在的基础上修改。如果操作为开始,那么就在优先级为的位置+1,否则在优先级为的位置-1。
查询就在这个询问所对应的时间查询,因为上面的操作相当于对主席树求了一边前缀和。
如果不明白具体操作就看一看代码吧~
代码
#include <cstdio>
#include <algorithm>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=100000;
const int maxk=4000000;
struct node
{
node *son[2];
int sum;
long long val;
};
node *root[maxn+10],tnode[maxk+10];
int cnt,stand[maxn+10];
int updata(node *x)
{
x->sum=x->son[0]->sum+x->son[1]->sum;
x->val=x->son[0]->val+x->son[1]->val;
return 0;
}
node* build(int l,int r)
{
node *x=&tnode[++cnt];
if(l==r)
{
x->sum=x->val=0;
return x;
}
int mid=(l+r)>>1;
x->son[0]=build(l,mid);
x->son[1]=build(mid+1,r);
updata(x);
return x;
}
node* modify(node *now,int l,int r,int pos,int v)
{
node *x=&tnode[++cnt];
if(l==r)
{
x->sum=now->sum+v;
x->val=now->val+v*stand[l];
return x;
}
int mid=(l+r)>>1;
if(pos<=mid)
{
x->son[0]=modify(now->son[0],l,mid,pos,v);
x->son[1]=now->son[1];
}
else
{
x->son[0]=now->son[0];
x->son[1]=modify(now->son[1],mid+1,r,pos,v);
}
updata(x);
return x;
}
long long getsum(node *now,int l,int r,int k)
{
if(k>=now->sum)
{
return now->val;
}
if(l==r)
{
return now->val/now->sum*k;
}
int mid=(l+r)>>1;
if(k<=now->son[0]->sum)
{
return getsum(now->son[0],l,mid,k);
}
else
{
return now->son[0]->val+getsum(now->son[1],mid+1,r,k-now->son[0]->sum);
}
}
struct data
{
int t,p,v;
data(int _t=0,int _p=0,int _v=0):t(_t),p(_p),v(_v){}
bool operator <(const data &other) const
{
return t<other.t;
}
};
bool cmp(data a,data b)
{
return a.p<b.p;
}
data d[maxn*2+10];
int n,m,tot;
long long last;
int main()
{
n=read();
m=read();
for(int i=1; i<=n; ++i)
{
int l=read(),r=read(),p=read();
d[i*2-1]=data(l,p,1);
d[i*2]=data(r+1,p,-1);
}
std::sort(d+1,d+n*2+1,cmp);
last=-1;
for(int i=1; i<=n*2; ++i)
{
if(d[i].p!=last)
{
last=d[i].p;
d[i].p=++tot;
stand[tot]=last;
}
else
{
d[i].p=tot;
}
}
std::sort(d+1,d+n*2+1);
root[0]=build(1,tot);
last=1;
for(int i=1; i<=m; ++i)
{
root[i]=root[i-1];
while((last<=n*2)&&(d[last].t<=i))
{
root[i]=modify(root[i],1,tot,d[last].p,d[last].v);
++last;
}
}
last=1;
for(int i=1; i<=m; ++i)
{
int x=read(),a=read(),b=read(),c=read(),k=(1ll*a*(last%c)+b)%c+1;
printf("%lld\n",last=getsum(root[x],1,tot,k));
}
return 0;
}