问题 G: 区间权值
时间限制: 1 Sec 内存限制: 128 MB
提交: 112 解决: 49
[提交] [状态] [讨论版] [命题人:admin]
题目描述
小Bo有n个正整数a1..an,以及一个权值序列w1…wn,现在他定义
现在他想知道的值,需要你来帮帮他
你只需要输出答案对109+7取模后的值
输入
第一行一个正整数n
第二行n个正整数a1..an
第三行n个正整数w1..wn
1≤n≤3×105
1≤ai≤107
1≤wi≤107
输出
输出答案对109+7取模后的值
样例输入
3 1 1 1 1 1 1
样例输出
10
方法:因为要将每一个区间的和加起来再与w相乘,所以可以求出对应的区间和。
AC代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)3e5 + 5;
const ll mod = 1e9+7;
ll a[maxn];
ll w[maxn];
ll suma[maxn];
ll sumaa[maxn];
int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);ios::sync_with_stdio(0),cin.tie(0);ll n;cin>>n;rep(i,1,n) {cin>>a[i];suma[i]=suma[i-1]+a[i]; //求出a数组的前缀和}rep(i,1,n) {cin>>w[i];}int start=0,end=n;sumaa[1]=(suma[end]-suma[start])%mod; //求出区间为1的所有区间的和start++;end--;int j;for(j=2;j<=(n+1)/2;j++){sumaa[j]=(sumaa[j-1]+suma[end]-suma[start])%mod; //可以推导出如区间为2的所有区间和等于区间为1的区间和加上a[2]到a[n-1]的和,以此类推start++;end--;}for(;j<=n;j++)sumaa[j]=sumaa[n-j+1]; //区间为n的区间和与区间为1的区间和相等,一次类推ll ans=0;rep(i,1,n) {ans=(ans+(w[i]*sumaa[i])%mod)%mod;}cout<<ans<<endl;return 0;
}