静态区间第k小。
主席树模板题
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,x,y,k; 4 struct node 5 { 6 int l,r,sum; 7 }num[3400000]; 8 int head[200050],a[200050],v[200050],pos[200050],w[200050],cnt,tot; 9 bool cmp(int x,int y) 10 { 11 return a[x]<a[y]; 12 } 13 void build(int l,int r,int &u) 14 { 15 u=++tot; 16 num[u].sum=0; 17 if(l==r) 18 return ; 19 int mid=(l+r)>>1; 20 build(l,mid,num[u].l); 21 build(mid+1,r,num[u].r); 22 } 23 void update(int l,int r,int val,int las,int &u) 24 { 25 u=++tot; 26 num[u].l=num[las].l; 27 num[u].r=num[las].r; 28 num[u].sum=num[las].sum+1; 29 if(l==r) 30 return ; 31 int mid=(l+r)>>1; 32 if(val<=mid) 33 update(l,mid,val,num[las].l,num[u].l); 34 else 35 update(mid+1,r,val,num[las].r,num[u].r); 36 } 37 int calc(int l,int r,int las,int u,int tk) 38 { 39 if(l==r) 40 return l; 41 int mid=(l+r)>>1; 42 int tmp=num[num[u].l].sum-num[num[las].l].sum; 43 if(tmp>=tk) 44 return calc(l,mid,num[las].l,num[u].l,tk); 45 else 46 return calc(mid+1,r,num[las].r,num[u].r,tk-tmp); 47 } 48 int main() 49 { 50 scanf("%d%d",&n,&m); 51 for(int i=1;i<=n;i++) 52 { 53 scanf("%d",&a[i]); 54 pos[i]=i; 55 } 56 sort(pos+1,pos+n+1,cmp); 57 for(int i=1;i<=n;i++) 58 { 59 if(a[pos[i]]!=a[pos[i-1]]||i==1) 60 w[++cnt]=a[pos[i]]; 61 v[pos[i]]=cnt; 62 } 63 build(1,cnt,head[0]); 64 for(int i=1;i<=n;i++) 65 update(1,cnt,v[i],head[i-1],head[i]); 66 while(m--) 67 { 68 scanf("%d%d%d",&x,&y,&k); 69 printf("%d\n",w[calc(1,cnt,head[x-1],head[y],k)]); 70 } 71 return 0; 72 }
离线的区间第k小当然也可以套整体二分。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,tot,cnt; 4 int ans[200050],c[200050],L=1e9,R=-1e9; 5 int pos[200050],lis[200050]; 6 void calc_add(int u,int v) 7 { 8 while(u<=n) 9 { 10 c[u]+=v; 11 u+=u&-u; 12 } 13 } 14 int calc_ask(int u) 15 { 16 int sum=0; 17 while(u) 18 { 19 sum+=c[u]; 20 u-=u&-u; 21 } 22 return sum; 23 } 24 struct node 25 { 26 int opt,x,l,r,val; 27 }t[400050],tl[400050],tr[400050]; 28 bool cmp (int a,int b) 29 { 30 return t[a].val<t[b].val; 31 } 32 void calc(int l,int r,int x,int y) 33 { 34 if(x==y) 35 { 36 for(int i=l;i<=r;++i) 37 if(t[i].opt) 38 ans[t[i].x]=lis[x]; 39 return ; 40 } 41 int mid=(x+y)>>1; 42 int totl=0,totr=0; 43 for(int i=l;i<=r;++i) 44 { 45 if(!t[i].opt) 46 { 47 if(t[i].val<=mid) 48 { 49 calc_add(t[i].x,1); 50 tl[++totl]=t[i]; 51 } 52 else 53 tr[++totr]=t[i]; 54 } 55 else 56 { 57 int tmp=calc_ask(t[i].r)-calc_ask(t[i].l-1); 58 if(tmp>=t[i].val) 59 tl[++totl]=t[i]; 60 else 61 { 62 t[i].val-=tmp; 63 tr[++totr]=t[i]; 64 } 65 } 66 } 67 for(int i=1;i<=totl;++i) 68 if(!tl[i].opt) 69 calc_add(tl[i].x,-1); 70 for(int i=1;i<=totl;++i) t[l+i-1]=tl[i]; 71 for(int i=1;i<=totr;++i) t[l+totl+i-1]=tr[i]; 72 calc(l,l+totl-1,x,mid); 73 calc(l+totl,r,mid+1,y); 74 } 75 int main() 76 { 77 scanf("%d%d",&n,&m);tot=n; 78 for(int i=1;i<=tot;++i) 79 { 80 scanf("%d",&t[i].val); 81 t[i].x=i; pos[i]=i; 82 }tot=n+m; 83 sort(pos+1,pos+n+1,cmp); 84 for(int i=1;i<=n;++i) 85 { 86 lis[i]=t[pos[i]].val; 87 t[pos[i]].val=i; 88 } 89 for(int i=n+1;i<=tot;++i) 90 { 91 scanf("%d%d%d",&t[i].l,&t[i].r,&t[i].val); 92 t[i].x=i-n; t[i].opt=1; 93 } 94 calc(1,tot,1,n); 95 for(int i=1;i<=m;++i) 96 printf("%d\n",ans[i]); 97 return 0; 98 }