poj 3397 線段樹區間合併

2021-07-23 22:48:41 字數 1690 閱讀 8538

不得不說線段樹的問題**真太長。。。。。。

這個問題大意剛開始給出乙個區間內的數,要麼是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 100010

using 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...