静态区间第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小

        离线的区间第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 }
整体二分

 


相关文章: