zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    [面试题]什么是面向对象编程
    面向对象编程的新手理解
    Object of type type is not JSON serializable
    STL---map
    STL---llist
    Div标签使用inline-block有间距
    STL---vector
    KMP算法
    算法06
    算法05
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934390.html
Copyright © 2011-2022 走看看