我在使用延迟传播实现分段树时遇到了麻烦。我刚刚阅读了有关分段树的内容,并尝试使用它来做一个简单的问题(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(" ");*/
}
}
}
答案 0 :(得分:1)
懒惰传播部分存在问题。它应该是:
tail[2*n+1].lazy=1-tail[2*n+1].lazy
而不是
tail[2*n+1].lazy=1