线段树区间修改区间查询模板(数据神坑)

题目:

对于一个数列,我们定义两种操作:
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

  

原文地址:https://www.cnblogs.com/inerbornthisway/p/7895541.html