BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)
和dynamic rankings这道题的思想一样
只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的
这道题还有负数,需要离散
1 #include <vector> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 50500 6 #define M1 100500 7 #define ll long long 8 #define dd double 9 #define inf 233333333 10 using namespace std; 11 12 int gint() 13 { 14 int ret=0,fh=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 16 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 17 return ret*fh; 18 } 19 ll gll() 20 { 21 ll ret=0;int fh=1; char c=getchar(); 22 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 23 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 24 return ret*fh; 25 } 26 27 struct SEG{ 28 ll sum[N1<<2],tag[N1<<2];int use[N1<<2],que[N1<<2],tl; 29 void pushdown(int l,int r,int rt) 30 { 31 if(!tag[rt]) return; 32 int mid=(l+r)>>1; 33 sum[rt<<1]+=tag[rt]*(mid-l+1); tag[rt<<1]+=tag[rt]; 34 sum[rt<<1|1]+=tag[rt]*(r-mid); tag[rt<<1|1]+=tag[rt]; 35 if(!use[rt<<1]) use[rt<<1]=1,que[++tl]=rt<<1; 36 if(!use[rt<<1|1]) use[rt<<1|1]=1,que[++tl]=rt<<1|1; 37 tag[rt]=0; 38 } 39 void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } 40 void update(int L,int R,int l,int r,int rt,int w) 41 { 42 if(!use[rt]) use[rt]=1,que[++tl]=rt; 43 if(L<=l&&r<=R){ sum[rt]+=(r-l+1)*w; tag[rt]+=w; return;} 44 int mid=(l+r)>>1; pushdown(l,r,rt); 45 if(L<=mid) update(L,R,l,mid,rt<<1,w); 46 if(R>mid) update(L,R,mid+1,r,rt<<1|1,w); 47 pushup(rt); 48 } 49 ll query(int L,int R,int l,int r,int rt) 50 { 51 if(L<=l&&r<=R) return sum[rt]; 52 int mid=(l+r)>>1; ll ans=0; pushdown(l,r,rt); 53 if(L<=mid) ans+=query(L,R,l,mid,rt<<1); 54 if(R>mid) ans+=query(L,R,mid+1,r,rt<<1|1); 55 return ans; 56 } 57 void clr(){ while(tl){ use[que[tl]]=0; sum[que[tl]]=0; tag[que[tl]]=0; que[tl--]=0; } } 58 }s; 59 struct node{int fl,l,r,ans,t;ll K;}a[N1],tmp[N1]; 60 int n,m,ma,nn; 61 int f[N1],w[N1],use[N1]; 62 63 void alldic(int l,int r,int ql,int qr) 64 { 65 if(l>r||ql>qr) return; 66 int mid=(l+r)>>1,i,j,S=ql,E;ll sum; 67 for(i=ql;i<=qr;i++) 68 { 69 if(a[i].fl==1){ 70 if(a[i].K>=mid){ s.update(a[i].l,a[i].r,1,n,1,1); use[i]=1; } 71 if(a[i].K>mid){ tmp[S++]=a[i]; } 72 }else{ 73 sum=s.query(a[i].l,a[i].r,1,n,1); 74 if(sum<a[i].K){ a[i].K-=sum; } 75 else{ f[a[i].t]=w[mid]; tmp[S++]=a[i]; use[i]=1; } 76 } 77 } 78 for(i=ql,E=S;i<=qr;i++) 79 { 80 if(!use[i]){ tmp[E++]=a[i]; } 81 else{ use[i]=0; } 82 } 83 for(i=ql;i<=qr;i++) a[i]=tmp[i]; 84 s.clr(); 85 alldic(mid+1,r,ql,S-1); alldic(l,mid-1,S,E-1); 86 } 87 88 int main() 89 { 90 scanf("%d%d",&n,&m); 91 int i,j; memset(f,-1,sizeof(f)); 92 for(i=1;i<=m;i++){ a[i].fl=gint(); a[i].l=gint(); a[i].r=gint(); a[i].K=gll(); a[i].t=i; if(a[i].fl==1) w[++ma]=a[i].K; } 93 sort(w+1,w+ma+1); ma=unique(w+1,w+ma+1)-(w+1); 94 for(i=1;i<=m;i++){ if(a[i].fl==1) a[i].K=lower_bound(w+1,w+ma+1,a[i].K)-w; } 95 alldic(1,ma,1,m); 96 for(i=1;i<=m;i++) if(f[i]!=-1) printf("%d\n",f[i]); 97 return 0; 98 }