思路

又是强制在线--主席树
每一次操作建一棵树
但实际用的的rt只有n个
所以实际内存是n230
我见到只开n*30的,不会,

错误

debug
以为每一秒建立一颗树
第一次
query没有递归
第二、三次
权值线段树的查询处理,就是到叶子节点的处理

代码

// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
using namespace std;
const int maxn=2e5+7;
const int inf=0x3f3f3f3f;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,lsh[maxn],rt[maxn],cnt;
struct edge {
    int s,e,p;
}rw[maxn];
vector< pair<int,int> > add,del;
struct node {
    int ch[2],siz;
    ll sum;
}e[maxn*30];
void build(int &now,int old,int l,int r,int k,int pp) {
    now=++cnt;
    e[now]=e[old];
    e[now].siz+=pp;
    e[now].sum+=(ll)pp*lsh[k];
    if(l==r) return;
    int mid=(l+r)>>1;
    if(k<=mid) build(e[now].ch[0],e[old].ch[0],l,mid,k,pp);
    else build(e[now].ch[1],e[old].ch[1],mid+1,r,k,pp);
} 
ll query(int now,int l,int r,int k) {
    if(l==r) return k*lsh[l];
    if(e[now].siz<=k) return e[now].sum;
    int mid=(l+r)>>1;
    if(e[e[now].ch[0]].siz>=k) return query(e[now].ch[0],l,mid,k);
    else return e[e[now].ch[0]].sum+query(e[now].ch[1],mid+1,r,k-e[e[now].ch[0]].siz);
}
void debug(int now,int l,int r) {
    if(l==r) {
        if(e[now].siz!=0) cout<<l<<" ";
        return;
    }
    int mid=(l+r)>>1;
    debug(e[now].ch[0],l,mid);
    debug(e[now].ch[1],mid+1,r);
}
int main() {
    //read
    n=read(),m=read();
    FOR(i,1,n) {
        rw[i].s=read(),rw[i].e=read(),rw[i].p=read();   
        lsh[i]=rw[i].p;
    }
    //lsh
    sort(lsh+1,lsh+1+n);
    int len=unique(lsh+1,lsh+1+n)-lsh-1;
    FOR(i,1,n) rw[i].p=lower_bound(lsh+1,lsh+1+n,rw[i].p)-lsh;
    //build
    FOR(i,1,n) {
        add.push_back(make_pair(rw[i].s,rw[i].p));
        del.push_back(make_pair(rw[i].e+1,rw[i].p));    
    }
    sort(add.begin(),add.end());
    sort(del.begin(),del.end());
    add.push_back(make_pair(inf,inf));
    del.push_back(make_pair(inf,inf));
    int ad=0,de=0;
    int js=0;
    FOR(i,1,n) {
        int tmp=rt[i-1];
        for(;add[ad].first==i;ad++) {
            build(rt[i],tmp,1,len,add[ad].second,1);
            tmp=rt[i];
        }
        for(;del[de].first==i;de++) {
            build(rt[i],tmp,1,len,del[de].second,-1);   
            tmp=rt[i];
        }
        if(!rt[i]) rt[i]=rt[i-1];
    }
    //work
    ll pre=1;
    FOR(i,1,m) {
        int id=read();
        int a=read(),b=read(),c=read();
        int k=(a*pre+b)%c+1;
        if(k<=e[rt[id]].siz) pre=query(rt[id],1,len,k);
        else pre=query(rt[id],1,len,e[rt[id]].siz);
        cout<<pre<<"\n";
    }
    return 0;
}