这是一道前缀和的问题
a[i]表示距离的前缀和 s[i]表示物品移动到1的价值的前缀和 b[i]表示物品数量的前缀和
在对于l-r移动到x 有三种情况
x<=l: 先全部移到1 对于每个储存点多移动了a[x]的距离 即 ans=s[r]-s[l-1]-(b[r]-b[l-1])a[x]
x>=r:先全部从1到x 每次多移了a[i]*b[i] 即s[i] ans=(b[r]-b[l-1])a[x]-(s[r]-s[l-1])
l<x<r: 把前面两个的情况综合起来
ps:注意多取模 有减法就 +mod)%mod
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e5+5;
const ll p=1e9+7;
ll n,m,a[N],b[N],s[N];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=2;i<=n;i++)cin>>a[i],a[i]=(a[i]+a[i-1])%p;
for(int i=1;i<=n;i++){
cin>>b[i];
s[i]=(a[i]*b[i]%p+s[i-1]+s[i])%p;
b[i]=(b[i]+b[i-1])%p;
}
while(m--)
{
ll x,l,r,ans;
cin>>x>>l>>r;
if(x<=l)
{
ans=(s[r]-s[l-1]+p)%p;
ans=(ans-(b[r]-b[l-1]+p)%p*a[x]%p+p)%p;
}
else if(x>=r)
{
ans=((b[r]-b[l-1]+p)%p*a[x]%p-(s[r]-s[l-1]+p)%p+p)%p;
}
else
{
ans=(s[r]-s[x-1]+p)%p; ans=(ans-(b[r]-b[x-1]+p)%p*a[x]%p+p)%p;
ans=(ans+(b[x]-b[l-1]+p)%p*a[x]%p-(s[x]-s[l-1]+p)%p)%p;
}
ans=(ans+p)%p;
cout<<ans<<endl;
}
return 0;
}

京公网安备 11010502036488号