题目:
一个数轴,每一个储物点会有一些东西,同时它们之间存在距离。
每次给个区间 ,查询把这个区间内所有储物点的东西运到另外一个储物点的代价是多少?
比如储物点图片说明图片说明 个东西,要运到储物点图片说明 ,代价为图片说明
dist 就是储物点间的距离。

ai 表示第i个储物点与第i+1个储物点的距离
bi 表示每个储物点的东西个数
图片说明


分析:
对于区间的物品移动到第图片说明位置,显然是
图片说明 .
因为是多组询问显然是不可能直接暴力计算的.
以为图片说明 是在变化的,我们可以预处理所有物品移动到指定的一个点的价值,我们指定移动到第一个物品的位置,根据位置先后维护移动代价的前缀和.
那么移动位置从第图片说明物品的位置 变成了图片说明 物品的位置。

  • 假如对于询问区间图片说明 ,图片说明 ,那么与我们预处理的代价,多了图片说明 区间物品的数量乘以图片说明 的代价.显然我们还要维护一个物品个数的前缀和,维护一个移动前i位置的物品代价前缀和,方便查询进行计算.
  • 假如对于询问区间图片说明 ,图片说明 ,我们转换一下思维,假如图片说明的物品在图片说明 位置了,要将它们还原到原位置,代价其实就是图片说明 区间物品的数量乘以图片说明 位置到图片说明 的距离 减去将图片说明区间物品移动到图片说明 位置的代价.
  • 那么对于图片说明 的情况,只需要将区间分成图片说明 两部分按照上面讨论算代价累加起来即可。
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn=2e5+10;
const int mod=1e9+7;

ll n,m;
ll num[maxn],a[maxn],b[maxn],sum[maxn];

int main()
{
    cin>>n>>m;
    for( int i=2;i<=n;i++ )
    {
        cin>>a[i];
        a[i]=(a[i]+a[i-1])%mod;
    }        
    for( int i=1;i<=n;i++ )
    {
        cin>>num[i];
        sum[i]=(a[i]*num[i]%mod+sum[i-1])%mod;
        num[i]=(num[i]+num[i-1])%mod;
    }
    while( m-- )
    {
        int x,l,r;
        cin>>x>>l>>r;
        ll ans=0;
        if( x<=l )
        {
            ans=(sum[r]-sum[l-1]+mod)%mod;
            ans=(ans-(num[r]-num[l-1]+mod)%mod*a[x]%mod+mod)%mod;
        }
        else if( x>=r )
        {
            ans=((num[r]-num[l-1]+mod)%mod*a[x]%mod-(sum[r]-sum[l-1]+mod)%mod+mod)%mod;
        }
        else
        {
            ans=(sum[r]-sum[x-1]+mod)%mod;
            ans=(ans-(num[r]-num[x-1]+mod)%mod*a[x]%mod+mod)%mod;
            ans=(ans+(num[x]-num[l-1]+mod)%mod*a[x]%mod-(sum[x]-sum[l-1]+mod)%mod+mod)%mod;
        }
        ans=(ans+mod)%mod;
        cout<<ans<<endl;
    }

}