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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树区间修改区间查询模板(数据神坑)相关的知识,希望对你有一定的参考价值。

题目:

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

  

 

以上是关于线段树区间修改区间查询模板(数据神坑)的主要内容,如果未能解决你的问题,请参考以下文章

模板线段树-单点修改,区间查询

[线段树模板] 区间修改 区间查询(详注)

线段树区间修改和查询和单点查询(线段树模板1)

模板线段树(区间加)

线段树单点修改区间修改单点查询值区间查询最大值最小值区间和之模板

树状数组实现区间修改+区间查询