NKOJ3754 数列游戏
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms
问题描述
给定一个长度为N的序列,首先进行A次操作,每次操作在Li和Ri这个区间加上一个数Ci。
然后有B次询问,每次询问Li到Ri的区间和。
初始序列都为0。
输入格式
第一行三个整数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。范围同上。
输出格式
对于每次询问,输出一行一个整数。
因为最后的结果可能很大,请对结果mod 1000000007。
样例输入
5 1 1
1 3 1
1 4
样例输出
3
提示
输入输出量巨大,强烈建议使用手工输入输出
解法:
添加操作用差分数组
差分数组求前缀和->实际数->再求前缀和->解决
#include<cstdio>
#include<iostream>
using namespace std;
const long long mod=1000000007;
const int need=1000004;
long long d[1000004];
//.........................................
template<class t1>
inline void in_(t1& d)
{
char t=getchar();
while(t<'0'||t>'9'){t=getchar();}
for(d=0;t>='0'&&t<='9';t=getchar())d=(d<<3)+(d<<1)-'0'+t;
}
//.........................................
int main()
{
int n,m,k;scanf("%d%d%d",&n,&m,&k);
long long c;
for(int i=1,a,b;i<=m;i++)
{
in_(a),in_(b),in_(c);//scanf("%d%d%I64d",&a,&b,&c);
d[a]=(d[a]+c)%mod;
d[b+1]=(d[b+1]-c)%mod;
}
for(int i=1;i<=n;i++) d[i]=(d[i-1]+d[i])%mod;
for(int i=1;i<=n;i++) d[i]=(d[i-1]+d[i])%mod;
for(int i=1,a,b,temp;i<=k;i++)
{
in_(a),in_(b);//scanf("%d%d",&a,&b);
temp=(d[b]-d[a-1])%mod;
printf("%d\n",temp>=0 ? temp : temp+mod);//可能为负,手工改正
}
}