• ABC: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.

     

    首先对于所有数减去k,这样就不用除(r-l+1), 然后我们发现所求的就是有多少对l,r,使得sum[r]-sum[l-1] >= 0, sum是减去k之后的序列的前缀和

    用树状数组对sum求有多少个顺序对,多加一个0这个数,代表从sum[r]-sum[0]对答案的贡献。

    由于sum[i]可能很大,所以需要离散化 用unique

    #include <bits/stdc++.h>
    #define ll long long
    const int mod=1e9+7;
    const int maxn=2e5+7;
    using namespace std;
    //int s[maxn];
    ll sum[maxn],t[maxn];
    ll tree[maxn];
    int nn,m;
    void add(int x)
    {
        while(x<=nn)//nn为上限,要大于离散化后的最大的数字,
        {
            tree[x]++;
            x+=x&-x;//向上更新,树状数组核心代码。此处就不解释了,不会的先学树状数组。
        }
    }
    ll query(int x)
    {
        ll num=0;
        while(x)
        {
            num+=tree[x];
            x-=x&-x;//向下求和
        }
        return num;
    }
    int main()
    {
        int n,k,a;
        scanf("%d %d",&n,&k);
        nn=n+10;
        for(int i=1;i<=n;i++){
            scanf("%d",&a);
            sum[i]=t[i]=sum[i-1]+a-k;
        }
        sort(t,t+n+1);
        m=unique(t,t+n+1)-t;
        for(int i=0;i<=n;i++){
            sum[i]=lower_bound(t,t+m+1,sum[i])-t+1;
        }
        ll ans=0;
        for(int i=0;i<=n;i++){
            ans+=query(sum[i]);
            add(sum[i]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
     
    不要忘记努力,不要辜负自己 欢迎指正 QQ:1468580561
  • 相关阅读:
    Python中列表
    Python中For循环
    While循环
    python中if else流程判断
    python中get pass用法
    python学习
    Forbidden Attack:7万台web服务器陷入被攻击的险境
    爱恨交织!我们经常抱怨却离不开的7种语言
    玩转大数据,你需要了解这8种项目类型!
    如何用 Python 实现 Web 抓取?
  • 原文地址:https://www.cnblogs.com/smallocean/p/9185573.html
Copyright © 2020-2023  润新知