2020杭电HDU-6827多校第六场Road To The 3rd Building(找规律求期望)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6827
博客园食用链接:https://www.cnblogs.com/lonely-wind-/p/13456765.html

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 1…n . Each tree has a cute value. The cute value of tree i i is s i s_i .

Kanade defines a plan as an ordered pair ( i , j ) (i,j) , here 1 i j n 1≤i≤j≤n . It means a student will appear at the position of the tree i i magically, walk along the road, and finally stop walking at the position of the tree j 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 ) (i,j) is 1 j i + 1 k = i j s k \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 n integers s i s_i — the cute value of each ginkgo tree, space-separated.

1 T 20 , 1 n 2 × 1 0 5 , 1 s i 1 0 9 1\leq T\leq 20,1\leq n\leq 2\times10^5,1\leq s_i\leq 10^9
It is guaranteed that n 1 0 6 \sum n\leq10^6

Output
For each testcase, output the answer in the fraction form modulo 1 0 9 + 7 10^9+7 in one line. That is, if the answer is f r a c P Q frac{P}{Q} , you should output P Q 1   m o d   ( 1 0 9 + 7 ) P⋅Q^{−1}\ mod\ (10^9+7) , where Q 1 Q^{−1} denotes the multiplicative inverse of Q Q modulo 1 0 9 + 7 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个数,现在任意选择一个区间求其平均值,你需要求出这个平均值的期望。

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

对于: 1 1 4 5 1 4
len=1: 1 \color{#FF3030}{1} 1 1 1 1 1
len=2:1 2 \color{#FF3030}{2} 2 2 2 1
len=3:1 2 3 \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

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

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

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

#define debug printf("@#$@#$\n")
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\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43906000/article/details/107875712
3rd