• [主席树]K-th Number


    正确解法:

    分块(超时)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <set>
     7 #include <map>
     8 #include <vector>
     9 #include <cctype>
    10 #include <sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int inf=0x7fffffff;
    14 const int N=100000+100;
    15 const int M=5000+10;
    16 const double PI=acos(-1.0);
    17 int B=1000;
    18 int n,m,a[N],num[N];
    19 int I,J,K;
    20 vector<int> buck[N/1000];
    21 int main()
    22 {
    23     scanf("%d %d",&n,&m);
    24     for(int i=0;i<n;i++)
    25     {
    26         scanf("%d",&a[i]);
    27         num[i]=a[i];
    28         buck[i/B].push_back(a[i]);
    29     }
    30     sort(num,num+n);
    31     for(int i=0;i<n/B;i++)
    32         sort(buck[i].begin(),buck[i].end());
    33     for(int i=0;i<m;i++)
    34     {
    35         scanf("%d %d %d",&I,&J,&K);
    36         int lb=0,ub=n-1;
    37         while(lb<=ub)
    38         {
    39             int md= lb+ub >>1;
    40             int x=num[md];
    41             int tl=I-1,tr=J,c=0;
    42             while(tl<tr &&tl%B!=0)  if(a[tl++]<=x)  c++;
    43             while(tl<tr &&tr%B!=0)  if(a[--tr]<=x)  c++;
    44             while(tl<tr)
    45             {
    46                 int b=tl/B;
    47                 c+=upper_bound(buck[b].begin(),buck[b].end(),x)-buck[b].begin();
    48                 tl+=B;
    49             }
    50             if(c>=K)    ub=md-1;
    51             else lb=md+1;
    52         }
    53         printf("%d
    ",num[lb]);
    54     }
    55 
    56 
    57     return 0;
    58 }
    View Code

    主席树:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <set>
     7 #include <map>
     8 #include <vector>
     9 #include <cctype>
    10 #include <sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int inf=0x7fffffff;
    14 const int N=100000+100;
    15 const int M=5000+10;
    16 const double PI=acos(-1.0);
    17 int n,m,a[N],num[N];
    18 int I,J,K;
    19 vector<int>buck[(1<<18)-1];
    20 void build(int rt,int l,int r)
    21 {
    22     if(l==r)
    23     {
    24         buck[rt].push_back(a[l]);
    25         return ;
    26     }
    27     int m= l+r >>1;
    28     build(rt<<1,l,m);
    29     build(rt<<1|1,m+1,r);
    30     buck[rt].resize(r-l+1);
    31     merge(buck[rt<<1].begin(),buck[rt<<1].end(),buck[rt<<1|1].begin(),buck[rt<<1|1].end(),buck[rt].begin());
    32 }
    33 int query(int L,int R,int x,int rt,int l,int r)
    34 {
    35     if(R<l||r<L)
    36         return 0;
    37     if(L<=l&&r<=R)
    38         return upper_bound(buck[rt].begin(),buck[rt].end(),x)-buck[rt].begin();
    39     int ans=0,m=l+r >>1;
    40     ans+=query(L,R,x,rt<<1,l,m);
    41     ans+=query(L,R,x,rt<<1|1,m+1,r);
    42     return ans;
    43 }
    44 int main()
    45 {
    46     scanf("%d %d",&n,&m);
    47     for(int i=1;i<=n;i++)
    48     {
    49         scanf("%d",&a[i]);
    50         num[i]=a[i];
    51     }
    52     sort(num+1,num+1+n);
    53     build(1,1,n);
    54     while(m--)
    55     {
    56         scanf("%d %d %d",&I,&J,&K);
    57         //J++;
    58         int lb=1,ub=n;
    59         while(lb<=ub)
    60         {
    61             int md=lb+ub >>1;
    62             int c=query(I,J,num[md],1,1,n);
    63             if(c>=K)    ub=md-1;
    64             else lb=md+1;
    65         }
    66         printf("%d
    ",num[lb]);
    67     }
    68 
    69     return 0;
    70 }
    View Code
    No matter how you feel, get up , dress up , show up ,and never give up.
  • 相关阅读:
    变更管理
    2020软件工程个人作业06——软件工程实践总结作业
    鸽子开发组---冲刺第七天
    冲刺第六天
    鸽子开发组---冲刺第五天
    鸽子开发组--冲刺第四天
    鸽子开发组--冲刺第三天
    鸽子开发组--冲刺第二天
    冲刺规划
    冲刺第一天
  • 原文地址:https://www.cnblogs.com/Kaike/p/10808572.html
Copyright © 2020-2023  润新知