zoukankan      html  css  js  c++  java
  • game

       评测传送门

    Description:

    给定n个数,求所以两两之间的差值的中位数。

    Data range:

    2 ≤ n ≤ 50000 , 2|a i

    Solution:

    ps: sm(small)是比mid小的差值的个数 bg(big)是大的 cnt是差值的总个数

    这些差值的总数是n*(n-1)/2个 从数据范围来看 是没有办法存起来的

    我们可以二分这个中位数

    对于我们二分的可能答案 可以求出所有的中位数中比它小的和大的数的个数

    根据这个就可以判断二分的值是偏小还是偏大啦(具体见code很好理解)

    但是当差值的总数是偶数时 中位数为中间两个数的平均数

    发现对于一个二分的一个值 sm==bg&&sm+bg==cnt时一定是出现的上面的那种情况

    这时我们需要找到中间的两个数 所以就有了第二次和第三次二分

    中间的两个数分别是sm<bg的最大值和sm>bg的最小值

    attention:  lower_bound()是找到第一个大于等于x的数的位置

          upper_bound()是找到第一个大于x的数的位置

    CODE

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define R register
     6 #define go(i,a,b) for(R int i=a;i<=b;++i)
     7 #define ll long long
     8 #define db double
     9 #define il inline
    10 #define M 50001
    11 #define inf 2100000000
    12 using namespace std;
    13 il int rd()
    14 {
    15     int x=0,y=1;;char c=getchar();
    16     while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
    17     while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}  
    18     return x*y;
    19 }
    20 int n,cnt,x,y,a[M];
    21 ll bg,sm;
    22 il void calc(int x)
    23 {
    24     go(i,1,n)
    25     {
    26         sm+=lower_bound(a+i+1,a+n+1,a[i]+x)-a-i-1;
    27         bg+=n-(upper_bound(a+i+1,a+n+1,a[i]+x)-a-1);
    28     }
    29 }
    30 int main()
    31 {
    32     freopen("1.in","r",stdin);
    33     freopen("1.out","w",stdout);
    34     n=rd();cnt=(ll)n*(n-1)/2;
    35     go(i,1,n) a[i]=rd();
    36     sort(a+1,a+n+1);
    37 
    38     int l=0,r=a[n]-a[1]+1,mid;
    39     while(l<=r)
    40     {
    41         mid=(l+r)>>1;
    42         sm=0,bg=0;calc(mid);
    43         if(bg==sm)
    44         {
    45             if(bg+sm==cnt) break;
    46             else {printf("%d",mid);return 0;}
    47         }
    48         if((abs(bg-sm)<(cnt-bg-sm))||(abs(bg-sm)==(cnt-bg-sm)&&(cnt%2))){printf("%d",mid);return 0;}
    49         if(bg>sm) l=mid+1;
    50         else r=mid-1;
    51     }
    52 
    53     l=0,r=a[n]-a[1]+1;
    54     while(l<=r)
    55     {
    56         mid=(l+r)>>1;
    57         sm=0;bg=0;calc(mid);
    58         if(sm<bg) x=mid,l=mid+1;
    59         else r=mid-1;
    60     }
    61     l=0,r=a[n]-a[1]+1;
    62     while(l<=r)
    63     {
    64         mid=(l+r)>>1;
    65         sm=0;bg=0;calc(mid);
    66         if(sm>bg) y=mid,r=mid-1;
    67         else l=mid+1;
    68     }
    69 
    70     printf("%d",(x+y)/2);
    71     return 0;
    72 }
    View Code
    光伴随的阴影
  • 相关阅读:
    PID算法控制直流电机笔记
    HAL库直流电机编码测速(L298N驱动)笔记
    HAl库控制L298N直流电机旋转笔记
    MQTT介绍与使用(转载)
    STM32中STD、HAL、LL库比较
    rpm检验是否被改动过
    find命令 参数
    会话管理测试时的注意点
    无权限修改用户组权限的状况一
    burpsuite + sqlmap 日志导出批量扫描
  • 原文地址:https://www.cnblogs.com/forward777/p/10369847.html
Copyright © 2011-2022 走看看