POJ 2777 線段樹 位運算

2021-07-28 04:48:29 字數 1866 閱讀 1829

poj 2777

有乙個長位l的區間,有t種顏色,進行o次操作,每次操作(1

≤n≤100000,1

≤t≤30

,1≤o

≤100000)

每次操作有兩種形式:

p a b c:將區間(a,b)染成顏色c

q a b:詢問區間(a,b)有多少種不同的顏色

每個點的初始顏色都是1

注意:a可能大於b

線段樹的區間更新

有兩種資訊,乙個是區間維護的資訊color表示某個區間有哪些顏色,還有乙個資訊是延遲標記資訊lazy陣列。

這道題可以用位運算來進行線段間的合併操作,就是用用乙個32位int型別的col變數表示某個區間有哪些顏色

知道兩個子節點有哪些顏色要求父親節點有哪些顏色的時候通過按位或(|)進行合併.

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=100005;

int n,s,m;//線段長度為n,一共有s種顏色,進行m種操作

int lazy[maxn*4];//延遲標記

int col[maxn*4];

void init()

void pushup(int rt)//rt的子節點已經更新好了,現在更新rt節點

void build(int l,int r,int rt)

int m=(l+r)/2;

build(l,m,rt*2);

build(m+1,r,rt*2+1);

pushup(rt);

}void pushdown(int rt)//節點rt已經更新好了,將標記下推

}void update(int l,int r,int x,int l,int r,int rt)

int m=(l+r)/2;

pushdown(rt);

if(l<=m)update(l,r,x,l,m,rt*2);

if(r>m)update(l,r,x,m+1,r,rt*2+1);

pushup(rt);

}int query(int l,int r,int l,int r,int rt)

int color1,color2;

int color_ans;

color1=0;

color2=0;

int m=(l+r)/2;

pushdown(rt);

if(l<=m)color1=query(l,r,l,m,rt*2);

if(r>m)color2=query(l,r,m+1,r,rt*2+1);

color_ans=color1 | color2;

return color_ans;

}void find_ans(int t)

cout

//題目中可能有l>r的情況

update(l,r,x,1,n,1);

}else

if(c=='p')

//題目中可能有l>r的情況

ans=query(l,r,1,n,1);

find_ans(ans);}}

}return0;}

/*6 7 4

c 1 6 2

p 1 5

c 4 2 7

p 6 1

*/

線段樹模板 poj2777

線段數塗色 include include using namespace std define maxn 100005 struct node tree maxn 4 bool visit 40 int sum void build int left,int right,int id tree i...

POJ2777 線段樹染色

初始顏色均為1,倆操作 修改 將 l,r 染為顏色z 查詢 l,r 的不同顏色數 1e5個點,1e5個操作,30種顏色 查詢 如果查詢維護區間顏色數,不滿足區間加法 顏色數較少,維護區間顏色狀態s val pushup 當前子樹s 左子樹s 右子樹s 修改 維護顏色替換標記lazy 注意pushdo...

poj2777線段樹 lazy思想

題意 有乙個長板子,多次操作,有兩種操作,第一種是給從a到b那段染一種顏色c,另一種是詢問a到b有多少種不同的顏色。這題更加讓我理解線段樹的結構了,特別是lazy思想的運用。事實上lazy思想就是個懶人的標記,若對於這個結點lazy標記為true,就代表不需要繼續查詢縮小的區間了。主要是在更新結點的...