不得不說線段樹的問題**真太長。。。。。。
這個問題大意剛開始給出乙個區間內的數,要麼是0要麼是1;
然後有如下操作:
0 i j:把區間i到j內的數全部變成0
1 i j:把區間i到j內的數全部變成1
2 i j:把區間i到j內的數0變成1,1變成0
3 i j:把區間i到j內的所有的1求出來
4 i j:求出區間i到j內最大連續的1;
這個問題的關鍵其實是操作2,因為這涉及到區間更新,所以會用到懶惰標記,用懶惰標記時,到2操作的時候,不能把原來的標記覆蓋掉
而是應該對於原來的標記取反,,,,這個地方懂了也就沒問題了。。。
(不過剛開始我還出現乙個問題,對於兩個求值得操作求法不一樣,,,這個注意!!)
#include #include #include #include #define maxn 100010using namespace std;
struct node
;node tree[4*maxn];
int tag[4*maxn];
int flag[maxn];
void xor(int now)
void up(int now,int l,int r)
if (tree[2*now+1].rm==r-mid)
if (tree[2*now].lom==(mid-l+1))
if (tree[2*now+1].rom==r-mid)
tree[now].res1=max(tree[now].res1,tree[2*now].rm+tree[2*now+1].lm);
tree[now].res2=max(tree[now].res2,tree[2*now].rom+tree[2*now+1].lom);
}void down(int now,int l,int r)
else if (tag[now]==0)
else if (tag[now]==2)
}void build(int now,int l,int r)
int mid=(l+r)>>1;
build(2*now,l,mid);
build(2*now+1,mid+1,r);
up(now,l,r);
}void update(int now,int l,int r,int tl,int tr,int val)
else if (val==1)
else
return ;
}down(now,l,r);
int mid=(l+r)>>1;
if (tr<=mid)
else if (tl>mid)
else
up(now,l,r);
}int query(int now,int l,int r,int tl,int tr,int val)
if (val==4)
}down(now,l,r);
int mid=(l+r)>>1;
if (tr<=mid)
else if (tl>mid)
else
else
}}int main()
build(1,1,n);
while(m--)
else}}
return 0;
}
poj 3397 線段樹區間合併
不得不說線段樹的問題 真太長。這個問題大意剛開始給出乙個區間內的數,要麼是0要麼是1 然後有如下操作 0 i j 把區間i到j內的數全部變成0 1 i j 把區間i到j內的數全部變成1 2 i j 把區間i到j內的數0變成1,1變成0 3 i j 把區間i到j內的所有的1求出來 4 i j 求出區間...
poj3667 線段樹(區間合併)
題意 有編號為1 n的n個房間,有兩種詢問 1.有人來訂連續的k間房,有的話返回第一間房的編號,否則返回0。2.有人退連續的從a開始的連續的k間房。1.該區間最大的連續空房數 2.該區間從最左邊起的最大的連續空房數 3.該區間從最右邊起的最大的連續空房數 根據以上三個資訊,每個非葉結點的資訊都可以由...
poj 3667 線段樹 區間合併
感想 沒有什麼說的了。越做線段樹越感覺自己水。這個我感覺自己就真坑了大家了。難的不會,簡單的也水不過了。哎,最近這是什麼情況啊!題目 題意 旅館有編號為1 n的房間,現在可能有m波人過了租房,每波人可能要定連續的d間房,如果有的話,編號盡量小,沒有的話就說0,也可能有d個人要退房,他們的房是連續的x...