离线操作听上去很简单,遗憾的是它强制在线。
每个时刻可以看成可持久化线段树中的一个版本,而每一个版本的线段树维护的是值某一段区间且在这个版本对应的时刻出现的数之和。
会发现同一时刻可能会有很多个数插入,这时可以对每个点记录版本,版本相同就不用更新了。
注意空间问题,并不对劲的空间让并不对劲的人调了一年。
#include<algorithm> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<stack> #include<vector> #define rep(i,x,y) for(register int i=(x);i<=(y);++i) #define dwn(i,x,y) for(register int i=(x);i>=(y);--i) #define re register #define maxn 200010 #define mi ((l+r)>>1) #define LL long long using namespace std; inline LL read() { LL x=0,f=1; char ch=getchar(); while(isdigit(ch)==0 && ch!=‘-‘)ch=getchar(); if(ch==‘-‘)f=-1,ch=getchar(); while(isdigit(ch))x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar(); return x*f; } inline void write(re LL x) { LL f=0;char ch[20]; if(!x){puts("0");return;} if(x<0){putchar(‘-‘);x=-x;} while(x)ch[++f]=x%10+‘0‘,x/=10; while(f)putchar(ch[f--]); putchar(‘\n‘); } LL tr[maxn<<6],rt[maxn],siz[maxn<<6],ls[maxn<<6],rs[maxn<<6],id[maxn<<6],pre=1,cnt=0; LL s[maxn],e[maxn],p[maxn],ord[maxn],n,q,mt; LL ti[maxn],ads[maxn],pla[maxn],num; inline void pu(re LL nd){tr[nd]=tr[ls[nd]]+tr[rs[nd]],siz[nd]=siz[ls[nd]]+siz[rs[nd]];} inline void build(re LL nd,re LL l,re LL r) { if(l==r){tr[nd]=siz[nd]=0;return;} ls[nd]=++cnt,rs[nd]=++cnt; build(ls[nd],l,mi),build(rs[nd],mi+1,r); } inline LL add(re LL nd,re LL l,re LL r,re LL idi,re LL x,re LL ad) { if(l==x&&r==x){tr[++cnt]=tr[nd]+ad,siz[cnt]=siz[nd]+((ad<0)?-1:1),id[cnt]=idi;return cnt;} if(r<x||x<l)return nd; LL lson=add(ls[nd],l,mi,idi,x,ad),rson=add(rs[nd],mi+1,r,idi,x,ad); if(id[nd]!=idi)id[++cnt]=idi,nd=cnt; ls[nd]=lson,rs[nd]=rson,pu(nd); return nd; } inline LL ask(re LL nd,re LL l,re LL r,re LL k) { if(siz[nd]<=k)return tr[nd]; if(siz[ls[nd]]<k)return tr[ls[nd]]+ask(rs[nd],mi+1,r,k-siz[ls[nd]]); else return ask(ls[nd],l,mi,k); } inline bool cmp(re LL x,re LL y){return p[x]<p[y];} inline bool cmp2(re LL x,re LL y){return ti[x]<ti[y];} int main() { n=read(),q=read(); rep(i,1,n)s[i]=read(),e[i]=read(),p[i]=read(),ord[i]=i; rt[0]=++cnt;build(1,1,n);num=0; sort(ord+1,ord+n+1,cmp); rep(i,1,n){ti[++num]=s[ord[i]],ads[num]=p[ord[i]],pla[num]=i,ti[++num]=e[ord[i]]+1,ads[num]=-p[ord[i]],pla[num]=i;} rep(i,1,num)ord[i]=i; sort(ord+1,ord+num+1,cmp2); rep(i,1,num) { if(ti[ord[i]]!=ti[ord[i-1]]){rt[ti[ord[i]]]=add(rt[ti[ord[i-1]]],1,n,ti[ord[i]],pla[ord[i]],ads[ord[i]]);} else {add(rt[ti[ord[i]]],1,n,ti[ord[i]],pla[ord[i]],ads[ord[i]]);} mt=max(mt,ti[ord[i]]); } int tmpt; rep(j,0,mt) { if(rt[j]){tmpt=rt[j];continue;} rt[j]=tmpt; } while(q--) { LL x=read(),a=read(),b=read(),c=read(),k=1+(pre*a+b)%c; LL ans=ask(rt[x],1,n,k); pre=ans;write(pre); } return 0; } /* 4 3 1 2 6 2 3 3 1 3 2 3 3 4 3 5 3 10 1 1 3 4 2 2 4 3 */
因为十分开心,就把zhing火龙的图放上来了。