POJ3468【线段树lazy操作】

上午理论AC,打到现在快吐了。。。
一个那么**Lazy操作打成这样,query操作和update操作都有问题,妈蛋,发现是mid<=s+1…真是蠢到家,明明是mid+1<=s卧槽连左和右都分不清。。。
什么是lazy?
lazy做法:
查询一个区间,如果这个节点的区间正好是满足,那么直接返回,眼睛都不眨一下,如果不是,就要让根的标志和他的子节点搞一搞,然后继续分下去,判断与mid的关系,因为是从根节点下去,所以他肯定是满足区间的,只是怎么分的问题,有两个是区间变小,分别是查询区间完全在mid右边和左边,还有就是mid就在区间里面那么切一切就好了。同理更新啊。。。。。。。。。瞎瘠薄搞吧,巨巨,画个树,然后拿各种区间,分分看就知道了。
贴上我的挫code………………..

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int INF=-0x3f3f3f3f;
const int N=100000;

struct st{
    LL left,right;
    LL sum;
    LL val;     //对该节点的下一层子节点而言的,不是对于其本身,所以其本身要本来就加上了这个value;
};
st q[N*4];
LL n;
int m;

void build(int num,LL L,LL R)
{
    q[num].left=L;
    q[num].right=R;
    q[num].val=0;
    if(L==R)
    {
        scanf("%I64d",&q[num].sum);
        return;
    }
    build(2*num,L,(L+R)/2);
    build(2*num+1,(L+R)/2+1,R);
    q[num].sum=q[2*num].sum+q[2*num+1].sum;
}

void update(int num,LL s,LL t,LL x)
{
    if(q[num].left==s&&q[num].right==t)
    {
        q[num].val+=x;
        q[num].sum+=x*(q[num].right-q[num].left+1);
        return;
    }
    if(q[num].left==q[num].right) return;
    if(q[num].val)
    {
        q[2*num].val+=q[num].val;
        q[2*num].sum+=q[num].val*(q[2*num].right-q[2*num].left+1);
        q[2*num+1].val+=q[num].val;
        q[2*num+1].sum+=q[num].val*(q[2*num+1].right-q[2*num+1].left+1);
        q[num].val=0;
    }

    LL mid=(q[num].left+q[num].right)/2;
    if(mid>=t)
        update(2*num,s,t,x);
    else if(mid+1<=s)
        update(2*num+1,s,t,x);
    else{
        update(2*num,s,mid,x);
        update(2*num+1,mid+1,t,x);
    }
    q[num].sum=q[2*num].sum+q[2*num+1].sum;
}

LL query(int num,LL s,LL t)
{
    if(q[num].left==s&&q[num].right==t)
        return q[num].sum;

    if(q[num].val)
    {
        q[2*num].val+=q[num].val;
        q[2*num].sum+=q[num].val*(q[2*num].right-q[2*num].left+1);
        q[2*num+1].val+=q[num].val;
        q[2*num+1].sum+=q[num].val*(q[2*num+1].right-q[2*num+1].left+1);
        q[num].val=0;
    }
    LL ans=0;
    LL mid=(q[num].left+q[num].right)/2;
    if(mid>=t)
        ans+=query(2*num,s,t);
    else if(mid+1<=s)
        ans+=query(2*num+1,s,t);
    else{
        ans+=query(2*num,s,mid);
        ans+=query(2*num+1,mid+1,t);
    }
    return ans;
}

int main()
{
    scanf("%I64d%d",&n,&m);
    build(1,1,n);
    while(m--)
    {
        char ss[5];
        LL a,b,c;
        scanf("%s",ss);
        if(strcmp(ss,"Q")==0)
        {
            scanf("%I64d%I64d",&a,&b);
            printf("%I64d
",query(1,a,b));
        }
        else{
            scanf("%I64d%I64d%I64d",&a,&b,&c);
            update(1,a,b,c);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934390.html