昨天在写带修改主席树的时候,咸鱼zcysky发现自己似乎根本不会写主席树

于是正好找个空复习下……

主席树的原理不用我扯了,主席树为啥能求k大,大概在它可以用历史版本存下区间的前缀和,求的时候差分下就能提出我要求的区间。

不过这么搞的话不要忘了离散化。

1.kth number

就是上面的裸题,不要手贱写bits就好。

 1 #include<iostream>
 2 #include<cstdio>
 3 #define N 100010
 4 #include<algorithm>
 5 #include<cstring>
 6 using namespace std;
 7 struct Node{int sum,ls,rs;}T[N*20];
 8 int cnt;
 9 void ins(int &num,int &x,int l,int r){
10     T[cnt++]=T[x];x=cnt-1;T[x].sum++;
11     if(l==r)return;
12     int mid=(l+r)/2;
13     if(num<=mid)ins(num,T[x].ls,l,mid);
14     else ins(num,T[x].rs,mid+1,r); 
15 }
16 int query(int i,int j,int k,int l,int r){
17     if(l==r)return l;
18     int t=T[T[j].ls].sum-T[T[i].ls].sum;
19     int mid=(l+r)/2;
20     if(k<=t)return query(T[i].ls,T[j].ls,k,l,mid);
21     else return query(T[i].rs,T[j].rs,k-t,mid+1,r);
22 }
23 struct A{
24     int x,idx;
25     bool operator<(const A &s)const{
26         return x<s.x;}
27 };
28 A a[N];
29 int rank[N],root[N];
30 int n,m;
31 int main(){
32     T[0].ls=T[0].rs=T[0].sum=0;root[0]=0;
33     while(scanf("%d%d",&n,&m)!=EOF){
34         for(register int i=1;i<=n;++i){
35             scanf("%d",&a[i].x);
36             a[i].idx=i;
37         }
38         sort(a+1,a+n+1);
39         for(int i=1;i<=n;i++)rank[a[i].idx]=i;
40         cnt=1;
41         for(int i=1;i<=n;i++){
42             root[i]=root[i-1];
43             ins(rank[i],root[i],1,n);
44         }
45         while(m--){
46             int i,j,k;
47             scanf("%d%d%d",&i,&j,&k);
48             int ans=a[query(root[i-1],root[j],k,1,n)].x;
49             printf("%d\n",ans);
50         }
51     }
52     return 0;
53 }
QAQ

相关文章:

  • 2022-12-23
  • 2021-12-30
  • 2021-06-19
  • 2021-11-10
  • 2022-01-17
  • 2022-12-23
  • 2022-02-09
猜你喜欢
  • 2022-12-23
  • 2021-10-23
  • 2021-11-02
  • 2022-12-23
相关资源
相似解决方案