牛客国庆集训派对Day4G-区间权值

版权声明:不念过去,不畏未来,一切都是过眼云烟。 https://blog.csdn.net/qq_34531807/article/details/83216148


题解:
a n s = ans=
f ( 1 , 1 ) + f ( 1 , 2 ) + . . . + f ( 1 , n ) + f(1,1)+f(1,2)+...+f(1,n)+
f ( 2 , 2 ) + f ( 2 , 3 ) + . . . + f ( 2 , n ) + f(2,2)+f(2,3)+...+f(2,n)+
. . . ...
f ( n 1 , n 1 ) + f ( n 1 , n ) + f(n-1,n-1)+f(n-1,n)+
f ( n , n ) f(n,n)
s [ i ] = a [ 1 ] + a [ 2 ] + . . . + a [ i ] s[i]=a[1]+a[2]+...+a[i]
a n s = ans=
s [ 1 ] w 1 + s [ 2 ] w 2 + s [ 3 ] w 3 + . . . + s [ n ] w n + s[1]w_1+s[2]w_2+s[3]w_3+...+s[n]w_n+
( s [ 2 ] s [ 1 ] ) w 1 + ( s [ 3 ] s [ 1 ] ) w 2 + . . . + ( s [ n ] s [ 1 ] ) w n 1 + (s[2]-s[1])w_1+(s[3]-s[1])w_2+...+(s[n]-s[1])w_{n-1}+
( s [ 3 ] s [ 2 ] ) w 1 + ( s [ 4 ] s [ 2 ] ) w 2 + . . . + ( s [ n ] s [ 2 ] ) w n 2 + (s[3]-s[2])w_1+(s[4]-s[2])w_2+...+(s[n]-s[2])w_{n-2}+
. . . ...
( s [ n 1 ] s [ n 2 ] ) w 1 + ( s [ n ] s [ n 2 ] ) w 2 + (s[n-1]-s[n-2])w_1+(s[n]-s[n-2])w_2+
( s [ n ] s [ n 1 ] ) w 1 (s[n]-s[n-1])w_1
这时将每一列相加,可得
s [ n ] w 1 + s[n]w_1+
( s [ n ] + s [ n 1 ] s [ 1 ] ) w 2 + (s[n]+s[n-1]-s[1])w_2+
( s [ n ] + s [ n 1 ] + s [ n 2 ] s [ 2 ] s [ 1 ] ) w 3 (s[n]+s[n-1]+s[n-2]-s[2]-s[1])w_3
. . . ...
s [ n ] w n s[n]w_n
这时就又需要一重前缀和了。
S [ i ] = s [ 1 ] + s [ 2 ] + . . . + s [ i ] S[i]=s[1]+s[2]+...+s[i]
最终 a n s = i = 1 n ( S [ n ] S [ n i ] S [ i 1 ] ) w i ans=\sum_{i=1}^{n}(S[n]-S[n-i]-S[i-1])wi
C o d e Code:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7,N=3e5+5;
int s[N],a[N],w[N],n;
long long S[N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		s[i]=(s[i-1]+a[i])%mod;
	}
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	for(int i=1;i<=n;i++)
		S[i]=(S[i-1]+s[i])%mod;
	long long ans=0;
	for(int i=1;i<=n;i++)
		ans=(ans+((S[n]-S[n-i]-S[i-1]+mod)%mod*w[i]%mod)%mod)%mod;
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34531807/article/details/83216148