好像真的没什么好说的,主席树维护一个差分就好了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 100020
#define LL long long
#define find(a) (lower_bound(cur+1,cur+1+cnt,(a))-cur)
using namespace std;
LL n,m,rt[maxn*10],cur[maxn*10],cnt,tot;
struct node{
LL ls,rs,k;//一共有k个节点sum,
LL sum;
node():ls(0),rs(0),k(0),sum(0){}
}nod[maxn*80];
struct quest{
LL x,pos,v;
quest(LL a=0,LL b=0,LL c=0):x(a),pos(b),v(c){}
bool operator <(const quest& b)const{return x<b.x;}
}q[maxn*10];
//pos表示插入还是删除 v是插入或者删除的数值
void insert(LL l,LL r,LL x,LL& y,LL v,LL pos){
y=++tot;nod[y].k=nod[x].k+pos;
nod[y].sum=nod[x].sum+(LL)cur[v]*pos;
if(l==r)return;
LL mid=l+r>>1;
nod[y].ls=nod[x].ls,nod[y].rs=nod[x].rs;
if(v>mid)insert(mid+1,r,nod[x].rs,nod[y].rs,v,pos);
else insert(l,mid,nod[x].ls,nod[y].ls,v,pos);
}
//查询前k个优先级任务的和
LL query(LL l,LL r,LL x,LL k){
if(nod[x].k<=k)return nod[x].sum;
if(l==r)return (LL)k*cur[l];
LL mid=l+r>>1,ll=nod[x].ls,rr=nod[x].rs;
if(nod[ll].k>=k)return query(l,mid,ll,k);
else return query(mid+1,r,rr,k-nod[ll].k)+nod[ll].sum;
}
LL last[maxn*80];
int main(){
scanf("%lld%lld",&n,&m);LL pp=0;
for(LL a,b,c,i=1;i<=n;i++){
scanf("%lld%lld%lld",&a,&b,&c);
cur[++cnt]=c;
q[++pp]=quest(a,1,c);
if(b<n)q[++pp]=quest(b+1,-1,c);
}sort(cur+1,cur+1+cnt);
cnt=unique(cur+1,cur+1+cnt)-cur-1;
sort(q+1,q+1+pp);
LL now=0;
for(LL i=1;i<=pp;i++){
insert(1,cnt,rt[i-1],rt[i],find(q[i].v),q[i].pos);
last[q[i].x]=rt[i];
}LL pre=1;
LL a,b,c,k;
for(int i=1;i<=100000;i++){
if(last[i])now=last[i];
last[i]=now;
}
for(LL x,i=1;i<=m;i++){
scanf("%lld%lld%lld%lld",&x,&a,&b,&c);
k=1+(a*pre+b)%c;
pre=query(1,cnt,last[x],k);
printf("%lld\n",pre);
}
return 0;
}