Newcoder 39 B.儲物點的距離(水~)
阿新 • • 發佈:2018-11-02
Description
一個數軸,每一個儲物點會有一些東西,同時它們之間存在距離。
每次給個區間 ,查詢把這個區間內所有儲物點的東西運到另外一個儲物點的代價是多少?
比如儲物點 有 個東西,要運到儲物點 ,代價為
就是儲物點間的距離。
Input
第一行兩個數表示
第二行 個數,第 個數表示第 個儲物點與第 個儲物點的距離
第三行 個數,表示每個儲物點的東西個數
之後 行每行三個數
表示查詢要把區間 儲物點的物品全部運到儲物點 的花費
每次查詢獨立
Output
對於每個詢問輸出一個數表示答案
答案對 取模
Sample Input
5 5
2 3 4 5
1 2 3 4 5
1 1 5
3 1 5
2 3 3
3 3 3
1 5 5
Sample Output
125
72
9
0
70
Solution
令
表示每個儲物點的位置,把區間
的東西全部移動到
,相當於把區間
的東西右移到
,把區間
的東西左移到
,以左移為例,直接考慮把區間
的物品移動到
位置的代價,即為
故維護一下
和
的字首和即可
查詢
Code
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=200005;
#define mod 1000000007
int add(int x,int y)
{
x+=y;
if(x>=mod)x-=mod;
return x;
}
int mul(int x,int y)
{
ll z=1ll*x*y;
return z-z/mod*mod;
}
int n,m,a[maxn],b[maxn],sum[maxn],res[maxn];
int main()
{
scanf("%d%d",&n,&m);
a[1]=0;
for(int i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
a[i]=add(x%mod,a[i-1]);
}
for(int i=1;i<=n;i++)scanf("%d",&b[i]),b[i]%=mod;
for(int i=1;i<=n;i++)sum[i]=add(sum[i-1],mul(a[i],b[i]));
for(int i=1;i<=n;i++)res[i]=add(res[i-1],b[i]);
while(m--)
{
int l,r,x;
scanf("%d%d%d",&x,&l,&r);
int ll=max(l,x),rr=max(r,x);
int ans=add(add(sum[rr],mod-sum[ll-1]),mod-mul(add(res[rr],mod-res[ll-1]),a[x]));
ll=min(l,x),rr=min(r,x);
ans=add(ans,add(mul(add(res[rr],mod-res[ll-1]),a[x]),add(sum[ll-1],mod-sum[rr])));
printf("%d\n",ans);
}
return 0;
}