#主席樹,離散,掃描線#洛谷 3168 [CQOI2015]任務查詢系統
阿新 • • 發佈:2020-08-19
分析
詢問顯然得預處理,考慮以優先順序建權值線段樹,
將優先順序離散化處理,那麼第\(k\)大可以用線段樹來求
那任務怎麼辦,考慮時間用掃描線的方法,按照時間建新的線段樹
把任務分成兩部分,在兩端差分,實際上每次修改只會修改一小部分,
所以用主席樹做,空間複雜度就能得到保證
程式碼
#include <cstdio> #include <cctype> #include <algorithm> #define rr register using namespace std; typedef long long lll; const int N=100011; int n,m,T,b[N],rt[N]; struct rec{int x,p;}a[N<<1]; struct Chair{ lll ww[N<<6],wc[N<<6]; int ls[N<<6],rs[N<<6],cnt; inline void build(int &rt,int l,int r){ rt=++cnt,ww[rt]=wc[rt]=0; if (l==r) return; rr int mid=(l+r)>>1; build(ls[rt],l,mid); build(rs[rt],mid+1,r); } inline void update(int &rt,int l,int r,int x,int z){ rr int trt=++cnt; ls[trt]=ls[rt],rs[trt]=rs[rt], ww[trt]=ww[rt],wc[trt]=wc[rt],rt=trt; if (l==r){ wc[rt]+=z,ww[rt]+=z*b[l]; return; } rr int mid=(l+r)>>1; if (x<=mid) update(ls[rt],l,mid,x,z); else update(rs[rt],mid+1,r,x,z); wc[rt]=wc[ls[rt]]+wc[rs[rt]], ww[rt]=ww[ls[rt]]+ww[rs[rt]]; } inline lll query(int rt,int l,int r,int kth){ if (l==r) return kth*b[l]; rr int mid=(l+r)>>1; return kth<=wc[ls[rt]]?query(ls[rt],l,mid,kth): query(rs[rt],mid+1,r,kth-wc[ls[rt]])+ww[ls[rt]]; } }Tre; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline void print(lll ans){ if (ans>9) print(ans/10); putchar(ans%10+48); } bool cmp(rec a,rec b){return a.x<b.x;} signed main(){ m=iut()<<1,T=iut(),Tre.cnt=0; for (rr int i=1;i<=m;i+=2){ a[i].x=iut(),a[i+1].x=iut()+1, a[i].p=iut(),a[i+1].p=-a[i].p, b[++n]=a[i].p; } sort(b+1,b+1+n),sort(a+1,a+1+m,cmp), n=unique(b+1,b+1+n)-b-1,Tre.build(rt[0],1,n); for (rr int i=1,j=0;i<=m;++i){ rr int op=1; if (a[i].p<0) op=-1,a[i].p*=op; for (;j<a[i].x;++j) rt[j+1]=rt[j]; if (j==T+1) break; rr int t=lower_bound(b+1,b+1+n,a[i].p)-b; Tre.update(rt[j],1,n,t,op); } for (rr lll lans=1;T;--T){ rr int X=iut(),A=iut(),B=iut(),C=iut(); rr int kth=1+(1ll*A*lans+B)%C; if (Tre.wc[rt[X]]<=kth) lans=Tre.ww[rt[X]]; else lans=Tre.query(rt[X],1,n,kth); print(lans),putchar(10); } return 0; }