有一天小妖精们又在做游戏。这个游戏是这样的。
妖精仓库的储物点可以看做在一个数轴上。每一个储物点会有一些东西,同时他们之间存在距离。
每次他们会选出一个小妖精,然后剩下的人找到区间[l,r][l,r]储物点的所有东西,清点完毕之后问她,把这个区间内所有储物点的东西运到另外一个仓库的代价是多少?
比如储物点ii有xx个东西,要运到储物点jj,代价为
x \times \mathrm{dist}( i , j )x×dist(i,j)
dist就是仓库间的距离。
当然啦,由于小妖精们不会算很大的数字,因此您的答案需要对19260817取模。
输入输出格式
输入格式:
第一行两个数表示n,mn,m
第二行n-1n−1个数,第ii个数表示第ii个储物点与第i+1i+1个储物点的距离
第三行nn个数,表示每个储物点的东西个数
之后mm行每行三个数x l r
表示查询要把区间[l,r][l,r]储物点的物品全部运到储物点x的花费
输出格式:
对于每个询问输出一个数表示答案
输入输出样例
输入样例#1: 复制
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
输出样例#1: 复制
125
72
9
0
70
//真恶心,各种取mod
注意 (a - b) % mod ==> (a - b + mod) % mod
f[i] = xi | d[x] - d[i] | = | xi * d[x] - xi * d[i] |
∑f[i] = ∑ xi * d[x] - d[x] * ∑ xi ; (d[i]为 1 到 i 的距离和)
所以只要统计xi * di 的前缀和,和xi 的前缀和即可
无mod的爆0代码,便于理解
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 200000 + 100;
int n,m;
int d[maxn],val[maxn],sx[maxn],xl[maxn];
int read() {
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
return x * f;
}
int main() {
n = read(), m = read();
for(int i = 2; i <= n; i++) {
d[i] = read();
d[i] = d[i - 1] + d[i];
}
for(int i = 1; i <= n; i++) {
val[i] = read();
sx[i] = sx[i - 1] + val[i];
xl[i] = xl[i - 1] + val[i] * d[i];
}
while(m--) {
int x = read(), l = read(), r = read(), sum = 0;
if(x <= l) {
sum = ( xl[r] - xl[l- 1] ) - d[x] * ( sx[r] - sx[l - 1] );
}
else if(x >= r) {
sum = d[x] * ( sx[r] - sx[l - 1] ) - ( xl[r] - xl[l- 1] );
}
else {
sum = d[x] * ( sx[x - 1] - sx[l - 1] ) - ( xl[x - 1] - xl[l- 1] );
sum += ( xl[r] - xl[x] ) - d[x] * ( sx[r] - sx[x] );
}
cout<<sum<<endl;
}
}
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 200000 + 100;
const int mod = 19260817;
long long n,m;
long long d[maxn],val[maxn],sx[maxn],xl[maxn];
long long read() {
long long x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
return x * f;
}
int main() {
n = read(), m = read();
for(int i = 2; i <= n; i++) {
d[i] = read();
d[i] = d[i - 1] + d[i];
d[i] %= mod;
}
for(int i = 1; i <= n; i++) {
val[i] = read();
sx[i] = sx[i - 1] + val[i];
sx[i] %= mod;
xl[i] = xl[i - 1] + val[i] * d[i];
xl[i] %= mod;
}
while(m--) {
long long x = read(), l = read(), r = read(), sum = 0;
if(x <= l) {
sum = ( ( xl[r] - xl[l- 1] + mod ) % mod -
d[x] * ( sx[r] - sx[l - 1] + mod ) % mod + mod ) % mod;
}
else if(x >= r) {
sum = ( d[x] * ( sx[r] - sx[l - 1] + mod ) % mod -
( xl[r] - xl[l- 1] + mod ) % mod + mod ) % mod;
}
else {
sum = ( d[x] * ( sx[x - 1] - sx[l - 1] + mod ) % mod -
( xl[x - 1] - xl[l- 1] + mod ) % mod + mod ) % mod;
sum += ( ( xl[r] - xl[x] + mod ) % mod -
d[x] * ( sx[r] - sx[x] + mod ) % mod + mod ) % mod;
sum %= mod;
}
cout<<sum<<endl;
}
}