按时间继承关系建立主席树(权值线段树) 线段树维护区间和、元素个数 #includecstdio#includevector#define int long longusing namespace std;const int N=1e5+5;const int SZ=5e6+6;int m,n;int tot;int lc[SZ],rc[SZ];in
按时间继承关系建立主席树(权值线段树)
线段树维护区间和、元素个数
#include<cstdio> #include<vector> #define int long long using namespace std; const int N=1e5+5; const int SZ=5e6+6; int m,n; int tot; int lc[SZ],rc[SZ]; int sum[SZ],sz[SZ]; int rt[N]; void pushup(int u){ sz[u]=sz[lc[u]]+sz[rc[u]]; sum[u]=sum[lc[u]]+sum[rc[u]]; } int cp(int u){//返回复制一个新的结点 ++tot, sz[tot]=sz[u],sum[tot]=sum[u]; lc[tot]=lc[u], rc[tot]=rc[u]; return tot; } int modify(int u,int v,int w,int l=1,int r=10000000){ int u2=cp(u),mid=(l+r)>>1; if(l==r)return sz[u2]+=w, sum[u2]+=v*w, u2; if(v<=mid)lc[u2]=modify(lc[u],v,w,l,mid); else rc[u2]=modify(rc[u],v,w,mid+1,r); return pushup(u2), u2; } int query(int u,int k,int l=1,int r=10000000){ if(k==sz[u])return sum[u]; if(l==r)return sum[u]/sz[u]*k; int mid=(l+r)>>1; if(k<=sz[lc[u]])return query(lc[u],k,l,mid); else return sum[lc[u]]+query(rc[u],k-sz[lc[u]],mid+1,r); } vector<pair<int,int> > a[N];//在时刻i发生的事件 signed main(){ scanf("%lld%lld",&m,&n); for(int i=1;i<=m;i++){ int s,e,p; scanf("%lld%lld%lld",&s,&e,&p); a[s].push_back(make_pair(p,1)); a[e+1].push_back(make_pair(p,-1)); } for(int i=1;i<=n;i++){ rt[i]=rt[i-1];// 继承 for(unsigned j=0;j<a[i].size();j++){ rt[i]=modify(rt[i],a[i][j].first,a[i][j].second); } } int x,a,b,c,k,pre=1; for(int i=1;i<=n;i++){ scanf("%lld%lld%lld%lld",&x,&a,&b,&c); k=1+(a*pre+b)%c; x=rt[x], k=min(sz[x],k); pre=query(x,k); printf("%lld\n",pre); } return 0; }