• 【CCPC2017哈尔滨B】K-th Number


    原题:

    求f(x)不好求,那么可以尝试求f(x>=m)

    求x为第k大出现了几次不好求,那么可以尝试求大于等于x的所有数作为第k大出现了几次

    那么可以二分x,然后把所有大于等于x的视为1,其他视为0

    问题转化为求有多少个区间,使得区间内1的个数>=k

    区间问题可以枚举左端点,然后考虑右端点

    显然右端点是递增的,所以不用二分,直接双指针扫一遍即可

    本题本质在于用第一句话提到的方法,模糊掉不同的数,使得统计变得容易

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 #define LL long long
     6 int n,a[110000],o;  LL m;
     7 int nx,nn;
     8 //LL s[110000];
     9 LL cclt(int x){
    10     //for(int i=1;i<=n;++i)  s[i]=s[i-1]+(a[i]>=x);
    11     int j=0,bwl=0;  LL cnt=0;
    12     for(int i=1;i<=n;++i){
    13         bwl-=(a[i-1]>=x);
    14         while(bwl<o && j<n)  bwl+=(a[++j]>=x);
    15         if(bwl<o)  break;
    16         cnt+=(n-j+1);
    17     }
    18     return cnt;
    19 }
    20 bool chck(int x){
    21     return cclt(x) >= m;
    22 }
    23 int bnrsch(){
    24     int l=nn,r=nx,md;
    25     while(l+1<r){
    26         md=(l+r)>>1;
    27         (chck(md) ? l : r)=md;
    28     }
    29     return chck(r) ? r : l;
    30 }
    31 void prvs(){
    32     nx=0,nn=1000000007;
    33 }
    34 int main(){
    35     int T;  cin>>T;
    36     while(T --> 0){
    37         scanf("%d%d%lld",&n,&o,&m);
    38         prvs();
    39         for(int i=1;i<=n;++i){
    40             scanf("%d",&a[i]);
    41             nx=max(nx,a[i]);
    42             nn=min(nn,a[i]);
    43         }
    44         printf("%d
    ",bnrsch());
    45     }
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    如何利用UltraEdit语法着色来编辑shell脚本
    css 运动背景
    页面加载进度条
    jScrollPane滚动条
    页面加载进度条改进版
    js页面新消息提示
    一道题
    jquery插件 展示信息
    冒泡排序和快速排序
    字体背景
  • 原文地址:https://www.cnblogs.com/cdcq/p/13132524.html
Copyright © 2020-2023  润新知