• 区间平均值(逆序对)


    区间平均值

    问题描述:
    有N个数,随机选择一段区间,如果这段区间的所有数的平均值在[l, r]中则你比较厉害。求你比较厉害的概率。
    输入格式:
    第一行有三个数N, l, r,含义如上描述。
    接下来一行有N个数代表每一个数的值。
    输出格式:
    输出一行一个分数a/b代表答案,其中a, b互质。 如果答案为整数则直接输出该整数即可。
    样例输入 1:
    4 2 3
    3 1 2 4
    样例输出 1:
    7/10
    样例输入 2:
    4 1 4
    3 1 2 4
    样例输出 2:
    1
    样例解释:
    塔外面有棵树。
    数据规模与约定:
    对于30%的数据, 1 ≤ N ≤ 104。
    对于60%的数据, 1 ≤ N ≤ 105。
    对于100%的数据, 1 ≤ N ≤ 5 × 105, 0 < l ≤ r ≤ 100。

    思路:
    要求 区间平均值>=l&&<=r 的个数

    现在我们来求区间平均值在1~r的个数和1~l(不包括l)的个数 前减后即为所求
    以求1~r为例
    (a[i]+a[i+1]+……+a[i+k-1])/k<=r
    (a[i]+a[i+1]+……+a[i+k-1])<=k*r
    (a[i]+a[i+1]+……+a[i+k-1])-k*r<=0
    (a[i]-r)+(a[i+1]-r)+……+(a[i+k-1]-r)<=0
    令c[i]=a[i]-r得到一个新数组c
    即求c数组区间和<=0的个数
    令s为数组c的前缀和数组
    c[i]+c[i+1]+…+c[i+k-1]<=0
    s[i+k-1]-s[i]<=0
    s[i+k-1]<=s[i]

    i< i+k-1
    s[i]>=s[i+k-1]
    即求s数组逆序对数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define lon long long
    using namespace std;
    const int maxn=500010;
    lon n,l,r,ans1,ans2,a[maxn],b1[maxn],b2[maxn],c[maxn];
    lon s1[maxn],s2[maxn];
    lon lowbit(lon x)
    {
        return x&(-x);
    }
    void add(lon x)
    {
        for(lon i=x;i<=n;i+=lowbit(i))
        c[i]++;
    }
    lon getsum(lon x)
    {
        lon ans=0;
        for(lon i=x;i>=1;i-=lowbit(i))
        ans+=c[i];
        return ans;
    }
    int main()
    {
        freopen("jian.in","r",stdin);
        freopen("jian.out","w",stdout);
        cin>>n>>l>>r;
        for(lon i=1;i<=n;i++)
        scanf("%d",&a[i]);
        for(lon i=1;i<=n;i++)
        {
            s1[i]=s1[i-1]+a[i]-l;
            b1[i]=s1[i];
            if(s1[i]<0) ans1++;
        }
        for(lon i=1;i<=n;i++)
        {
            s2[i]=s2[i-1]+a[i]-r;
            b2[i]=s2[i];
            if(s2[i]<=0) ans2++;
        }
        sort(s1+1,s1+n+1);
        sort(s2+1,s2+n+1);
        lon t1=unique(s1+1,s1+n+1)-s1-1;
        lon t2=unique(s2+1,s2+n+1)-s2-1;
        for(lon i=1;i<=n;i++)
        {
            lon pos=lower_bound(s1+1,s1+t1+1,b1[i])-s1;
            b1[i]=pos;
            pos=lower_bound(s2+1,s2+t2+1,b2[i])-s2;
            b2[i]=pos;
        }
        for(lon i=n;i>=1;i--)
        {
            ans1+=getsum(b1[i]);
            add(b1[i]+1);
        }
        memset(c,0,sizeof(c));
        for(lon i=n;i>=1;i--)
        {
            ans2+=getsum(b2[i]);
            add(b2[i]);
        }
        lon up=ans2-ans1;
        lon down=n*(n+1)/2;
        if(up%down==0)
        cout<<up/down;
        else cout<<up/__gcd(up,down)<<"/"<<down/__gcd(up,down);
        fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    spring源码解析四( spring事务)
    Epoll的本质(内部实现原理)转载
    Gitlab+Jenkins+Docker+K8S实现CI/CD
    AIOps
    云运维的关键有哪些?
    Nginx代理Portainer
    nginx+tomcat+mysql进行负载均衡
    Docker安装及容器创建
    运维常用的linux命令操作
    Arm64安装docker和docker-compose
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070904.html
Copyright © 2020-2023  润新知