zoukankan      html  css  js  c++  java
  • [树状数组]Meaningful Mean

    题目描述

    You are given an integer sequence of length N, a= {a1,a2,…,aN}, and an integer K.
    a has N(N+1)⁄2 non-empty contiguous subsequences, {al,al+1,…,ar} (1≤l≤r≤N). Among them, how many have an arithmetic mean that is greater than or equal to K?

    Constraints
    All input values are integers.
    1≤N≤2×105
    1≤K≤109
    1≤ai≤109
     

    输入

    Input is given from Standard Input in the following format:
    N K
    a1
    a2
    :
    aN

    输出

    Print the number of the non-empty contiguous subsequences with an arithmetic mean that is greater than or equal to K.

    样例输入

    3 6
    7
    5
    7
    

    样例输出

    5
    

    提示

    All the non-empty contiguous subsequences of a are listed below:
    {a1} = {7}
    {a1,a2} = {7,5}
    {a1,a2,a3} = {7,5,7}
    {a2} = {5}
    {a2,a3} = {5,7}
    {a3} = {7}
    Their means are 7, 6, 19⁄3, 5, 6 and 7, respectively, and five among them are 6 or greater. Note that {a1} and {a3} are indistinguishable by the values of their elements, but we count them individually.

     
    思路:先将a[1~n]都自减k;则区间[l,r]需满足sum[l~r]>=0;即sum[r]>=sum[l-1];    即求有多少对[l,r]使得sum[r]>=sum[l-1];
    预处理前缀和得到sum[1~n]; 接着仿照树状数组求逆序数的方法求sum[i]>=sum[j]的对数(1<=j<i;  i作为r,j作为l-1,  则[j+1,i]是一可行区间,此处考虑不到[1,i]这个区间需额外判断);
    AC代码:
    #include <iostream>
    #include<cstdio>
    #include<algorithm>
    #define lowbit(x) x&(-x)
    typedef long long ll;
    using namespace std;
    
    ll a[200010];
    int b[200010];
    ll c[200010];
    int n,k;
    
    struct s{
      ll num;int id;
    }sum[200010];
    
    bool cmp(s x,s y){
      if(x.num==y.num) return x.id<y.id;
      return x.num<y.num;
    }
    
    bool cmp2(s x,s y){
      return x.id<y.id;
    }
    
    void add(int x,int val){
       for(int i=x;i<=n;i+=lowbit(i)){
           c[i]+=val;
       }
    }
    
    ll getsum(int x){
       ll ret=0;
       for(int i=x;i>=1;i-=lowbit(i)){
           ret+=c[i];
       }
       return ret;
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            a[i]-=k,sum[i].num=sum[i-1].num+a[i],sum[i].id=i;
        }
        sort(sum+1,sum+1+n,cmp);
        for(int i=1;i<=n;i++) b[sum[i].id]=i;
        sort(sum+1,sum+1+n,cmp2);
        ll ans=0;
        for(int i=1;i<=n;i++){
            if(sum[i].num>=0) ans++;
            ans+=getsum(b[i]);
            add(b[i],1);
        }
        printf("%lld
    ",ans);
        return 0;
    }
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    gimp 语言设置
    gnome 3.4 评测
    linux 添加PATH路径
    永中office2012 linux版 使用初步感受
    Bio per常规用法(1、读取序列)
    blast程序 介绍 简介
    genewise运行过程中遇到的错误及其解决方法
    gnome3 隐藏标题栏
    Bio per常规用法(2、翻译蛋白)
    genewise 编译过程中遇到的 getline冲突
  • 原文地址:https://www.cnblogs.com/lllxq/p/9228328.html
Copyright © 2011-2022 走看看