复赛模拟-19-11-08-T1区间和的和

区间和的和

题目描述

输入一个长度为n的数组a,a包括(n+1)n/2个区间。每个区间所有数的和,被称为区间和,求所有(n+1)n/2个区间和的和。由于数值较大,输出 mod 1e9+7 的结果。

对于30%的数据,1<=n<=100 ;
对于50%的数据, 1<=n<=1000;
对于100%的数据,1<=n<=100000。

解:

看到这一题呢,感觉应该可以先推一下,可能会有一点点的规律。然后我就手推了一下

数:1 2 3
区间:
1
2
3
1 2
2 3
1 2 3

出现次数
1 3
2 4
3 3

数:1 2 3 4
区间:
{1}
{2}
{3}
{4}
{1 2}
{2 3}
{3 4}
{1 2 3}
{2 3 4}
{1 2 3 4}

出现次数
1 3
2 6
3 6
4 4

数:1 2 3 4 5
区间:
{1}
{2}
{3}
{4}
{5}
{1 2}
{2 3}
{3 4}
{4 5}
{1 2 3}
{2 3 4}
{3 4 5}
{1 2 3 4}
{2 3 4 5}
{1 2 3 4 5 }

出现次数
1 5
2 8
3 9
4 8
5 5

区间:
{1}
{2}
{3}
{4}
{5}
{6}
{1 2}
{2 3}
{3 4}
{4 5}
{5 6}
{1 2 3}
{2 3 4}
{3 4 5}
{4 5 6}
{1 2 3 4}
{2 3 4 5}
{3 4 5 6}
{1 2 3 4 5}
{2 3 4 5 6}
{1 2 3 4 5 6}

出现次数
1 6
2 10
3 12
4 12
5 10
6 6

数:1 2 3 4 5 6 7 8 9 10
区间:
{1}
{2}
{3}
{4}
{5}
{6}
{7}
{8}
{9}
{10}
{1 2}
{2 3}
{3 4}
{4 5}
{5 6}
{6 7}
{7 8}
{8 9}
{9 10}
{1 2 3}
{2 3 4}
{3 4 5}
{4 5 6}
{5 6 7}
{6 7 8}
{7 8 9}
{8 9 10}
{1 2 3 4}
{2 3 4 5}
{3 4 5 6}
{4 5 6 7}
{5 6 7 8}
{6 7 8 9}
{7 8 9 10}
{1 2 3 4 5}
{2 3 4 5 6}
{3 4 5 6 7}
{4 5 6 7 8}
{5 6 7 8 9}
{6 7 8 9 10}
{1 2 3 4 5 6}
{2 3 4 5 6 7 }
{3 4 5 6 7 8}
{4 5 6 7 8 9 }
{5 6 7 8 9 10}
{1 2 3 4 5 6 7}
{2 3 4 5 6 7 8}
{3 4 5 6 7 8 9}
{4 5 6 7 8 9 10}
{1 2 3 4 5 6 7 8}
{2 3 4 5 6 7 8 9}
{3 4 5 6 7 8 9 10}
{1 2 3 4 5 6 7 8 9}
{2 3 4 5 6 7 8 9 10}
{1 2 3 4 5 6 7 8 9 10}

出现的次数
1 10
2 18
3 24
4 28
5 30
6 30
7 28
8 24
9 18
10 10

然后我推了这么多,发现区间里第i个数,在所有区间里面出现的总次数是** i*(n-i+1) **
在计算区间和的和的时候,计算每个区间出现的次数,然后乘以数值就可以计算了。
但是因为这一题要取模所以要注意一下,可能有些需要开long long ,当时评测的时候评测机针对我。后来改的时候,把所有的int改成了long long就过了。

代码:
#include
using namespace std;
long long n;
long long ans;
const long long k=1e9+7;
int main()
{
	freopen("sum.in","r",stdin);
	freopen("sum.out","w",stdout);
	scanf("%lld",&n);
	for (int i=1;i<=n;i++)
	{
		long long x;
		scanf("%lld",&x);
		ans=(ans+x*i%k*(n-i+1)%k)%k;
	}
	printf("%lld\n",ans);
	return 0;
} 

你可能感兴趣的:(题解)