具有延迟传播的Segment树中的实现困难

时间:2013-09-20 18:24:12

标签: algorithm data-structures segment-tree

我在使用延迟传播实现分段树时遇到了麻烦。我刚刚阅读了有关分段树的内容,并尝试使用它来做一个简单的问题(http://www.codechef.com/problems/FLIPCOIN),但我得到了错误的答案。请帮我实施。这是我的代码(如果你更喜欢ideone:http://ideone.com/SHVZ5y):

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
#include <map>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <queue>

#define s(x) scanf("%d",&x)
#define sil(x) scanf("%llu",&x)
#define sd(x) scanf("%ld",&x)

#define FOR(i,a,b) for( typeof(a) i=(a); i<(b); ++i)               // exclusive for
#define FORR(i,a,b) for( typeof(a) i=(a-1) ; i>=(b); --i)
#define REP(k,a,b) for(typeof(a) k=(a); k <= (b); ++k)          // inclusive for
#define REPR(i,a,b) for( typeof(a) i=(a) ; i>=(b); --i)
#define ALL(c) (c).begin(), (c).end()  
#define PB push_back 
#define MP make_pair 
#define SZ(x) ((int)((x).size()))
#define SRT(v) std::sort(ALL(v))
#define CTN(x) std::cout<<x<<'\n'                               //cout with newline
#define CTS(x) std::cout<<x<<" "                                //cout with space
#define CLR(x) std::memset(x,0,sizeof(x))
#define FILL(x,n) std::fill_n(x,sizeof(x),n)
#define DBGA(x,n) {FOR(i,0,n) cout<<x[i]<<" "; CTN(" ");}
//#define NL printf("\n")

typedef std::vector<int> VI;
typedef std::vector<long long int> VL;
typedef std::vector<std::string> VS;
typedef std::map<int,int> MI;
typedef std::pair<int,int> PII;
typedef unsigned long long ull;
typedef long long ll;


using namespace std;


struct node{
    int h;  //number of head
    int t;  //number of tail
    int lazy;
    node()
    {
        h=0;
        t=0;
        lazy=0;
    }
}tree[300000];
void build_tree(int n,int a,int b)
{
    //cout<<"wo"<<endl;
    if(a>b)
        return;
    if(a==b)
    {
        tree[n].h=0;
        tree[n].t=1;
        //cout<<tree[n]<<" "<<a<<" "<<b<<" "<<n<<endl;
        return;
    }
    build_tree(2*n+1,a,(a+b)/2);
    build_tree(2*n+2,(a+b)/2+1,b);
    tree[n].t=tree[2*n+1].t+tree[2*n+2].t;
    //cout<<tree[n]<<" "<<a<<" "<<b<<" "<<n<<endl;
}
int query(int n,int ql,int qr,int l,int r)
{

    if(tree[n].lazy!=0)
    {
        int tmp=tree[n].h;
        tree[n].h=tree[n].t;
        tree[n].t=tmp;
        if(r!=l)
        {
            tree[2*n+1].lazy=1;
            tree[2*n+2].lazy=1;
        }
        tree[n].lazy=0;
    }
    if(l>qr || r<ql)
        return 0;
    if(l>=ql  && r<=qr)
        return tree[n].h;

        return query(2*n+1,ql,qr,l,(l+r)/2)+query(2*n+2,ql,qr,(l+r)/2+1,r);
}
void update(int n,int ul,int ur,int l,int r)
{
    if(tree[n].lazy!=0)
    {
        int tmp=tree[n].h;
        tree[n].h=tree[n].t;
        tree[n].t=tmp;
        if(r!=l)
        {
            tree[2*n+1].lazy=1;
            tree[2*n+2].lazy=1;
        }
        tree[n].lazy=0;
    }
    if(l>ur || r<ul)
        return ;
    if(l>=ul  && r<=ur)
        {
            int tmp=tree[n].h;
            tree[n].h=tree[n].t;
            tree[n].t=tmp;
            if(r!=l)
            {
                tree[2*n+1].lazy=1;
                tree[2*n+2].lazy=1;
            }
            return;

        }


            update(2*n+1,ul,ur,l,(l+r)/2);
            update(2*n+2,ul,ur,(l+r)/2+1,r);
            tree[n].h=tree[2*n+1].h+tree[2*n+2].h;
            tree[n].t=tree[2*n+1].t+tree[2*n+2].t;

}


int main()
{
    std::ios_base::sync_with_stdio(false);
    int n;cin>>n;
    build_tree(0,0,n-1);
    int q;cin>>q;
    while(q--)
    {
        int t;cin>>t;int l,r;cin>>l>>r;
        if(t)
        {
            cout<<query(0,l,r,0,n-1)<<'\n';
        }
        else
        {
            update(0,l,r,0,n-1);
            /*CTN(" ");
            FOR(i,0,7)
                cout<<i<<" "<<tree[i].h<<'\n';
            CTN(" ");*/

        }
    }


}

1 个答案:

答案 0 :(得分:1)

懒惰传播部分存在问题。它应该是:

tail[2*n+1].lazy=1-tail[2*n+1].lazy

而不是

tail[2*n+1].lazy=1