SP3946 MKTHNUM - K-th Number(整體二分)
阿新 • • 發佈:2018-12-16
思路
整體二分的板子題,沒什麼思路好說
程式碼
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; struct Query{ int type,pos,val,l,r,k,aid; }Query[110000],lx[110000],rx[110000]; int ans[10000],n,m,qid,aid,minx=0x3f3f3f3f,maxx=-0x3f3f3f3f; namespace BIT{ int bit[110000]; int lowbit(int x){ return x&(-x); } void add(int pos,int val){ while(pos<=n){ bit[pos]+=val; pos+=lowbit(pos); } } int query(int pos){ int ans=0; while(pos){ ans+=bit[pos]; pos-=lowbit(pos); } return ans; } }; void divide(int L,int R,int l,int r){//L,R 值域 l,r 操作序列 if(l>r) return; int lt=0,rt=0; if(L==R){ for(int i=l;i<=r;i++) if(Query[i].aid) ans[Query[i].aid]=L; return; } int mid=(L+R)>>1; for(int i=l;i<=r;i++){ if(Query[i].type==1){//修改 if(Query[i].val<=mid){ BIT::add(Query[i].pos,1); lx[++lt]=Query[i]; } else rx[++rt]=Query[i]; } else{//查詢 int cnt=BIT::query(Query[i].r)-BIT::query(Query[i].l-1); if(cnt<Query[i].k){ Query[i].k-=cnt; rx[++rt]=Query[i]; } else lx[++lt]=Query[i]; } } for(int i=l;i<=r;i++) if(Query[i].type==1&&Query[i].val<=mid) BIT::add(Query[i].pos,-1); for(int i=1;i<=lt;i++) Query[l+i-1]=lx[i]; for(int i=1;i<=rt;i++) Query[l+lt+i-1]=rx[i]; divide(L,mid,l,l+lt-1); divide(mid+1,R,l+lt,r); } int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); Query[++qid].pos=i; Query[qid].type=1; Query[qid].val=x; maxx=max(maxx,x); minx=min(minx,x); } for(int i=1;i<=m;i++){ Query[++qid].type=2; scanf("%d %d %d",&Query[qid].l,&Query[qid].r,&Query[qid].k); Query[qid].aid=++aid; } divide(minx,maxx,1,qid); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }