区间权值
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1048576K,其他语言2097152K 64bit IO Format: %lld
题目描述
输入描述:
第一行一个正整数 n
第二行 n 个正整数 a1..an
第三行 n 个正整数 w1..wn
输出描述:
输出答案对 109+7 取模后的值
示例1
输入
复制 3 1 1 1 1 1 1
输出
复制
10
备注:
1≤ n≤ 3x 10^5^ 1≤ ai≤ 10^7^ 1≤ wi≤ 10^7^
题解:
吐槽一下,官方题解有点小错误,应该是打错了。。。
题目是求公式,我们将式子化简:
for(l = 1-->n)
for(r = l -->n)
f(l,r)
f(1,1)+f(1,2)....+f(1,n)
+f(2,2)+f(2,3)+....+f(2,n)
+....
+f(n,n)
我们再拆一下:
a1w1+(a1w2+a2w2)+(a1+a2+a3)w3+.(a1+a2+...+an)wn
+a2w1+(a2+a3)w2+....+(a2+a3+...+an)w(n-1)
+......
是不是感觉有点规律了
我们用sum[]来求前缀和,这样括号里面都可以用sum来表示
然后我们将所有w1合并,将所有w2合并,能得到:
(sum[1]-sum[0]+sum[2]-sum[1]+sum[3]........+sum[n]-sum[n-1])w1=(sum[n]-sum[0])w1
w2也合并:(sum[n]+sum[n-1]-sum[1]-sum[0])w2=(sum[n]-sum[0])+sum[n-1]-sum[1]
.....
wi的系数就是sum[n-i+1]-sum[i-1]+wi-1的系数
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+9; const int mod=1e9+7; ll w[300004],sum[maxn],a[maxn]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; sum[i]=(sum[i-1]+a[i])%mod; } for(int i=1;i<=n;i++)cin>>w[i]; ll ans=0; ll tot=0; for(int i=1;i<=n;i++) { tot=(tot+(sum[n-i+1]-sum[i-1]+mod)%mod)%mod; ans=(ans+tot*w[i]%mod)%mod; } cout<<ans; }