BZOJ3932: [CQOI2015]任务查询系统
n<=100000个带权区间,m<=100000个询问,每次问覆盖某个点的所有区间的权值的前K小的和,强制在线。
差分一下就变主席树了嘛。。然而调了半天。。
(若是此题入门可以看下其他人的博客)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 //#include<iostream> 6 using namespace std; 7 8 int n,m; 9 #define maxn 200011 10 struct Eve 11 { 12 int pos,v;bool type; 13 bool operator < (const Eve &b) const {return pos<b.pos;} 14 }eve[maxn];int le=0; 15 int lisan[maxn],li=0; 16 17 #define maxm 4000011 18 #define LL long long 19 struct SMT 20 { 21 struct Node 22 { 23 int son[2]; 24 int cnt; LL sum; 25 }a[maxm]; 26 int size,n; 27 void clear(int m) {n=m;size=0;a[0].cnt=a[0].sum=0;} 28 void insert(int pre,int &rt,int L,int R,int num,bool type) 29 { 30 rt=++size; 31 a[rt].cnt=a[pre].cnt+(type?1:-1); 32 a[rt].sum=a[pre].sum+lisan[num]*(type?1:-1); 33 if (L==R) {a[rt].son[0]=a[rt].son[1]=0;return;} 34 const int mid=(L+R)>>1; 35 if (num<=mid) insert(a[pre].son[0],a[rt].son[0],L,mid,num,type),a[rt].son[1]=a[pre].son[1]; 36 else insert(a[pre].son[1],a[rt].son[1],mid+1,R,num,type),a[rt].son[0]=a[pre].son[0]; 37 } 38 void insert(int pre,int &rt,int num,bool type) {insert(pre,rt,1,n,num,type);} 39 }smt; 40 41 int rt[maxn]; 42 int main() 43 { 44 scanf("%d%d",&n,&m); 45 for (int i=1,x,y,v;i<=n;i++) 46 { 47 scanf("%d%d%d",&x,&y,&v); 48 eve[++le]=(Eve){x,v,1}; 49 eve[++le]=(Eve){y+1,v,0}; 50 lisan[++li]=v; 51 } 52 sort(lisan+1,lisan+1+li);li=unique(lisan+1,lisan+1+li)-lisan-1; 53 for (int i=1;i<=le;i++) eve[i].v=lower_bound(lisan+1,lisan+1+li,eve[i].v)-lisan; 54 sort(eve+1,eve+1+le); 55 56 smt.clear(li); 57 for (int i=1;i<=le;i++) smt.insert(rt[i-1],rt[i],eve[i].v,eve[i].type); 58 59 LL last=1; 60 for (int i=1,x,y,z,w;i<=m;i++) 61 { 62 scanf("%d%d%d%d",&x,&y,&z,&w); 63 int K=(1ll*y*last+z)%w+1; 64 int p=upper_bound(eve+1,eve+1+le,(Eve){x,1,1})-eve-1; 65 66 p=rt[p];int L=1,R=li; LL ans=0; 67 K=min(K,smt.a[p].cnt); 68 while (L<R) 69 { 70 const int mid=(L+R)>>1; 71 if (smt.a[smt.a[p].son[0]].cnt>=K) 72 p=smt.a[p].son[0],R=mid; 73 else ans+=smt.a[smt.a[p].son[0]].sum,K-=smt.a[smt.a[p].son[0]].cnt,L=mid+1,p=smt.a[p].son[1]; 74 } 75 if (smt.a[p].cnt) ans+=smt.a[p].sum/smt.a[p].cnt*K; 76 printf("%lld\n",(last=ans)); 77 } 78 return 0; 79 }