直接用主席树维护下分数和个数就行了,思路挺好想的,不过比赛的时候我死活都没往主席树上想。。。唉。。。
然后需要注意的地方是,
1,区间更新时需要标记永久化,也就是标记不下放。
2,开64倍空间。一般开结构体会多用一些空间,所以空间比较紧的时候可以改成数组。
最后说说坑点,RE返回T。。。不过开64倍空间是最稳妥的。
#pragma comment(linker,"/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=100010; const int INF=1e9+10; int N,M,X;ll P; int L,R,D; int x,a,b,c,K; struct Query { ll pts;int cnt; friend Query operator+(Query A,Query B) { return (Query){A.pts+B.pts,A.cnt+B.cnt}; } }; int ls[maxn*64],rs[maxn*64]; ll pts[maxn*64]; int cnt[maxn*64]; int tot; int rt[maxn]; int build(int l,int r) { int k=++tot; pts[k]=cnt[k]=0; ls[k]=rs[k]=-1; if(l==r) return k; int m=(l+r)>>1; ls[k]=build(l,m); rs[k]=build(m+1,r); return k; } int update(int L,int R,ll D,int l,int r,int x) { int k=++tot; pts[k]=pts[x];cnt[k]=cnt[x]; ls[k]=ls[x];rs[k]=rs[x]; if(L<=l&&r<=R){ pts[k]+=D; cnt[k]++; return k; } int m=(l+r)>>1; if(L<=m) ls[k]=update(L,R,D,l,m,ls[k]); if(R>m) rs[k]=update(L,R,D,m+1,r,rs[k]); return k; } Query query(int p,int l,int r,int k) { Query res={pts[k],cnt[k]}; if(l==r) return res; int m=(l+r)>>1; if(p<=m) return res+query(p,l,m,ls[k]); else return res+query(p,m+1,r,rs[k]); } struct Target { int L,R,D; friend bool operator<(Target A,Target B) { return A.D<B.D; } void read() { scanf("%d%d%d",&L,&R,&D); } };Target target[maxn]; ll bin(int l,int r,int x,int K) { ll res=0; while(l<=r){ int m=(l+r)>>1; Query tmp=query(x,1,X,rt[m]); if(tmp.cnt<=K) l=m+1,res=max(res,tmp.pts); else r=m-1; } return res; } void debug(int k,int l,int r) { if(k==-1) return; printf("l=%2d r=%2d ",l,r); //tr[k].out(); int m=(l+r)>>1; debug(ls[k],l,m); debug(rs[k],m+1,r); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE while(~scanf("%d%d%d%I64d",&N,&M,&X,&P)){ REP(i,1,N) target[i].read(); sort(target+1,target+N+1); tot=0; rt[0]=build(1,X); REP(i,1,N){ L=target[i].L,R=target[i].R,D=target[i].D; rt[i]=update(L,R,D,1,X,rt[i-1]); } ll res=1,pre=1; REP(i,1,M){ scanf("%d%d%d%d",&x,&a,&b,&c); K=(1LL*a*pre+b)%c; res=bin(0,N,x,K); if(pre>P) res*=2; printf("%I64d ",pre=res); } } return 0; }