Sum of product of pairs https://vjudge.net/problem/AtCoder-abc177_c
根据乘法结合律,对于某一个数a[i],求其与位于其后的每一个数的乘积之和,
即a[i]*(a[i+1]+a[i+2]...)
用树状数组求每个前缀和之差,再与当前的数相乘。
特点:
1.数据较大,用long long
2.树状数组中求前缀和的函数改为ret=(ret+e[x])%mod或ret+=e[x];ret%=mod;
减法的结果求模,(在减法里+mod)%mod
#include<algorithm>
#include<math.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#define ll long long
#define INF 0x3f3f3f3f
#define For(i,a,b) for(long long i=a;i<b;i++)
#define lm(x) 1<<(x)
using namespace std;
#define N 200005
const ll mod=1e9+7;
ll e[N],a[N];int n;ll ans;
ll lbt(int x){
return x&(-x);
}
void upd(int x,int v){
for(;x<=N;x+=lbt(x)){
e[x]+=v;
}
}
ll tsum(int x){
ll ret=0;
for(int i=x;x>0;x-=lbt(x)){
ret=(ret+e[x])%mod;
}
return ret;
}
int main()
{ios::sync_with_stdio(false);
cin>>n;
For(i,1,n+1){
cin>>a[i];
upd(i,a[i]);
}
ll end=tsum(n)%mod;
For(i,1,n){
ans+=a[i]*(end-tsum(i)+mod)%mod;
ans%=mod;
}
cout<<ans<<endl;
return 0;
}