线段树区间修改区间查询模板(数据神坑)
题目:
对于一个数列,我们定义两种操作:
A L R C – 在区间L至R上的所有数加上C
B L R – 输出区间L到R上所有数的和
为了简单起见,数列的初始值全都是0
Input:
输入有多组,处理到文件结束。
对于每一组输出,第一行是三个整数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:
5 1 1 1 3 1 1 4
Sample Output:
3
long long sumv[maxn*4],addv[maxn*4]; long long a[maxn]; void build(int o,int l,int r) { if( l == r) sumv[o] = a[l]; else{ int m = l+(r-l)/2; build(o*2,l,m); build(o*2+1,m+1,r); sumv[o] = sumv[o*2] + sumv[o*2+1]; } } { build(1,1,n);//main函数中的调用 } void pushup(int o) { sumv[o] = sumv[o*2]+sumv[o*2+1]; } void pushdown(int o,int l ,int r) { if(addv[o]) { addv[o*2] += addv[o]; addv[o*2+1] += addv[o]; int m = l+(r-l)/2; sumv[o*2] += addv[o]*(m-l+1); sumv[o*2+1] += addv[o]*(r-m); addv[o] = 0; } } void update(int o,int l,int r,int ql,int qr,long long add) { if(ql <= l && qr >= r) { addv[o] += add; sumv[o] += add*(r-l+1); return; } pushdown(o,l,r); int m = l+(r-l)/2; if(ql <= m) update(o*2,l,m,ql,qr,add); if(qr >= m+1) update(o*2+1,m+1,r,ql,qr,add); pushup(o); } long long query(int o,int l,int r,int ql,int qr) { if(ql <= l && qr >= r) return sumv[o]; pushdown(o,l,r); int m = l+(r-l)/2; long long ans =0; if(ql <= m) ans += query(o*2,l,m,ql,qr); if(qr >= m+1) ans += query(o*2+1,m+1,r,ql,qr); return ans; }
针对这道题:
1.long long sumv[maxn*4],addv[maxn*4];
long long a[maxn];
会ml
2.两个大的int a,b相乘取模,要这样:
( (long long)a * (long long)b ) % MOD