Title Link
https://www.lydsy.com/JudgeOnline/problem.php?id=3932
Title Solution
Each process is divided into two operations: the start process and the end process. The priority is discretized and then sorted by time.
Build a chairman tree, the interval is the discrete priority size, each time build a root.
For each operation, set the time as ii and the priority as pp. if the current time ii has not been operated, then modify it on the basis of rooti − 1rooti − 1. Otherwise, modify it on the basis of rootirooti. If the operation is start, then it is + 1 at the priority of PP, otherwise - 1 at the priority of PP.
The query is at the time corresponding to this query, because the above operation is equivalent to finding the prefix sum of one side of the tree.
If you don't understand the specific operation, take a look at the code~
Code
#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;
}