zoukankan      html  css  js  c++  java
  • luogu P1627 [CQOI2009]中位数

    传送门

    要求有多少个长度为奇数的区间满足某个数为区间中位数

    这样的区间,大于中位数的数个数 等于 小于中位数的数个数

    用类似于前缀和的方法,设(X_i)(i)和数(b)形成的区间内,大于(b)的数个数减去小于(b)的数个数的值,每次从前面那个位置转移过来,加上这个位置的贡献救星

    最后用两个桶统计(b)左边和右边的(X_i)为某个值的个数,分别记为(l_i r_i),然后答案为(sum_{i,j}l_ir_j (i+j==0))

    注意负下标处理和两个初值要赋

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define inf 999999999
    
    using namespace std;
    const int N=100000+10;
    il LL rd()
    {
        re LL x=0,w=1;re char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n,b,w,a[N],x[N],l[N<<1],r[N<<1];
    LL ans;
    
    int main()
    {
      n=rd(),b=rd();
      for(int i=1;i<=n;i++)
        {
          a[i]=rd();
          if(a[i]==b) w=i;
        }
      l[n]=r[n]=1;
      for(int i=w+1;i<=n;i++) x[i]=x[i-1]+(a[i]>b?1:-1),++r[x[i]+n];
      for(int i=w-1;i>=1;i--) x[i]=x[i+1]+(a[i]>b?1:-1),++l[x[i]+n];
      for(int i=0;i<=(n<<1);i++) ans+=1ll*l[i]*r[(n<<1)-i];
      printf("%lld
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    chmod命令
    ls命令
    数组值去重-小技巧
    使用redis接管session
    使用redis接管cookie
    redis操作封装类
    HTTP协议详解
    Linux网络编程--多播
    Live555 分析(三):客服端
    Live555 分析(二):服务端
  • 原文地址:https://www.cnblogs.com/smyjr/p/9681370.html
Copyright © 2011-2022 走看看