junior19

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

10471: 数列游戏 I

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 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;
}


posted on 2017-03-14 16:13  junior19  阅读(235)  评论(0编辑  收藏  举报