10471: 数列游戏 I
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 63 Solved: 13
[Submit][Status][Web Board]
Description
给定一个长度为N的序列,首先进行A次操作,每次操作在Li和Ri这个区间加上一个数Ci。然后有B次询问,每次询问Li到Ri的区间和。
初始序列都为0。
Input
第一行一个整数T,表示有T组数据。
对于每组数据,第一行三个整数N A B。(1<=N<=1000000,1<=A<=N,A<=B<=N)
接下来A行,每行三个数Li Ri Ci。(1<=Li<=N,Li<=Ri<=N,|Ci|<=100000000000000)。
接下来B行,每行两个数 Li Ri。范围同上。
Output
对于每次询问,输出一行一个整数。因为最后的结果可能很大,请对结果mod 1000000007。
Sample Input
1
5 1 1
1 3 1
1 4
Sample Output
3
HINT
Source
思路:差分数列,如有个数组a, 差分数列为d, d[i]=a[i]-a[i-1],因此改变某段区间的值时改变首尾元素的值即可。# include <iostream> # include <cstring> # include <cstdio> # include <algorithm> # define INF 0x3f3f3f3f const long long MOD = 1000000007; using namespace std; long long arr[1000001], s[1000001], c; int main() { int t, n, a, b, l, r; scanf("%d",&t); while(t--) { memset(arr, 0, sizeof(arr)); memset(s, 0, sizeof(s)); scanf("%d%d%d",&n,&a,&b); while(a--) { scanf("%d%d%lld",&l,&r,&c); arr[l] = (arr[l] + c) % MOD; arr[r+1] = (arr[r+1] - c) % MOD; } for(int i=1; i<=n; ++i) { arr[i] = (arr[i] + arr[i-1])% MOD;//复原数组 s[i] = (s[i-1] + arr[i]) % MOD;//前缀和 } while(b--) { scanf("%d%d",&l,&r); printf("%lld\n",((s[r]-s[l-1])%MOD+MOD)%MOD); } } return 0; }