zoukankan      html  css  js  c++  java
  • 2020杭电HDU-6827多校第六场Road To The 3rd Building(找规律求期望)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6827
    CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/107875712

    Problem Description
    Because of the thriller adventure game The 3rd Building, there are fewer and fewer students who would like to go to the 3rd Building. So few students are working in the studio in the 3rd Building. Students are even more reluctant to go to the 3rd Building for experiments, which are also annoying.

    Kanade takes responsibility to improve this status. She thinks it a good idea to decorate the ginkgo trees along the road to the 3rd Building, making them cute. There are n ginkgo trees that are planted along the road, numbered with (1…n). Each tree has a cute value. The cute value of tree (i) is (s_i).

    Kanade defines a plan as an ordered pair ((i,j)), here (1≤i≤j≤n). It means a student will appear at the position of the tree (i) magically, walk along the road, and finally stop walking at the position of the tree (j). The cute level of a plan is the average of the cute value of the trees visited. Formally, the cute level of plan ((i,j)) is (frac{1}{j-i+1}sum_{k=i}^js_k)

    Kanade wants to know the mathematical expectation of the cute level if a student will take a plan among all these plans in a uniformly random way. But she is busy with learning Computer Networking, would you help her?

    Input
    The first line of the input contains an integer T — the number of testcases. You should process these testcases independently.

    The first line of each testcase contains an integer n — the number of ginkgo trees.

    The second line of each testcase contains (n) integers (s_i) — the cute value of each ginkgo tree, space-separated.

    (1leq Tleq 20,1leq nleq 2 imes10^5,1leq s_ileq 10^9)
    It is guaranteed that (sum nleq10^6)

    Output
    For each testcase, output the answer in the fraction form modulo (10^9+7) in one line. That is, if the answer is (frac{P}{Q}), you should output (P⋅Q^{−1} mod (10^9+7)), where (Q^{−1}) denotes the multiplicative inverse of (Q) modulo (10^9+7).

    Sample Input
    3
    3
    1 3 2
    6
    1 1 4 5 1 4
    9
    7325 516 56940 120670 16272 15007 337527 333184 742294

    Sample Output
    83333336
    188888893
    303405448

    Hint
    The answer to the first testcase is 25/12.

    题目大意:给你n个数,现在任意选择一个区间求其平均值,你需要求出这个平均值的期望。

    一个区间的平均值,也就是(frac{sum a_i}{len}),那么每次我们都需要对(len)取逆元,如果枚举数的话,区间长度不一样很难搞,所以我们考虑枚举区间长度,那么事情就变得简单了许多,我们只需要判断该区间长度下每个数出现的次数,然后将其对应的值乘上去最后做个加法,就是该区间长度下能够取得的值了,最后我们再除以一个区间长度就OK了。那么怎么判断每个区间长度下的每个数的出现次数呢?其实也很好办,我们直接手动绘制两个表就好了:

    对于: 1 1 4 5 1 4
    len=1:(color{#FF3030}{1}) 1 1 1 1 1
    len=2:1 (color{#FF3030}{2}) 2 2 2 1
    len=3:1 2 (color{#FF3030}{3}) 3 2 1
    (-------)
    len=4:1 2 3 3 2 1
    len=5:1 2 2 2 2 1
    len=6:1 1 1 1 1 1

    是不是发现一个很有趣的现象?也就是说我们很容易计算出每个长度下的分子!!,我们可以用前缀和(sum)先记录一下,然后我们再做个(ssum),用来表示每个长度下的分子。那么就很容易得到:(ssum[i]=ssum[i-1]+sum[n-i+1]-sum[i-1])
    那么我们就很容易得出如下代码:

    ssum[1]=sum[n];
    for (int i=2; i<=n/2; i++)
    	ssum[i]=(ssum[i-1]+sum[n-i+1]-sum[i-1]+mod)%mod;
    ssum[n]=sum[n];
    for (int i=n-1; i>=n/2+1; i--)
    	ssum[i]=(ssum[i+1]+sum[i]-sum[n-i]+mod)%mod;
    

    当然看着,上面的图,我们很容易观察到他是一个偶数,它虽然对称,但它没有中心,那么我们很容易猜想奇数会出现一个中心,那么简单画一下就是:

    1 1 1 1 1
    1 2 2 2 1
    1 2 3 2 1
    1 2 2 2 1
    1 1 1 1 1

    那么很容易发现就第(frac{n}{2}+1)行比较特殊,我们单独拎出来计算就是了。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    #define debug printf("@#$@#$
    ")
    typedef long long ll;
    const int mac=2e5+10;
    const int mod=1e9+7;
    
    ll qpow(ll a,ll b)
    {
        ll ans=1; 
        a%=mod;
        while (b){
            if (b&1) ans=ans*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return ans;
    }
    
    ll sum[mac],ssum[mac];
    int a[mac];
    
    int main(int argc, char const *argv[])
    {
        int t,n;
        scanf ("%d",&t);
        while (t--){
            scanf ("%d",&n);
            for (int i=1; i<=n; i++){
                scanf ("%d",&a[i]);
                sum[i]=(sum[i-1]+a[i])%mod;
            }
            if (n&1){
                ssum[1]=sum[n];
                for (int i=2; i<=n/2; i++)
                    ssum[i]=(ssum[i-1]+sum[n-i+1]-sum[i-1]+mod)%mod;
                ssum[n/2+1]=(ssum[n/2]+a[n/2+1])%mod;
                ssum[n]=sum[n];
                for (int i=n-1; i>=n/2+2; i--)
                    ssum[i]=(ssum[i+1]+sum[i]-sum[n-i]+mod)%mod;
            }
            else {
                ssum[1]=sum[n];
                for (int i=2; i<=n/2; i++)
                    ssum[i]=(ssum[i-1]+sum[n-i+1]-sum[i-1]+mod)%mod;
                ssum[n]=sum[n];
                for (int i=n-1; i>=n/2+1; i--)
                    ssum[i]=(ssum[i+1]+sum[i]-sum[n-i]+mod)%mod;
            }
            ll ans=0;
            for (int i=1; i<=n; i++){
                ans=(ans+ssum[i]*qpow(i,mod-2)%mod)%mod;
            }
            ans=((ans*2%mod) * qpow(1LL*n*(n+1),mod-2)%mod);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    vb学习笔记
    spfa模版
    spfa slf优化
    接口总结
    SAP屏幕穿透
    判断可编辑字段,用户输入的数据是否为纯数字(包含带小数点的小数)
    对于ALV中的可编辑字段,当输入的数据不满足某种条件时,我们需要将它恢复到修改前的数据,并刷新ALV。但是可编辑的字段刷新后仍然时修改后的数据,此处记录一种方法。
    ALV中可编辑字段数据变化时,对变化的数据进行操作。
    通过UPDATE 往数据库中更新数据
    SE16N 中设置为可编辑状态
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13456765.html
Copyright © 2011-2022 走看看