Poj2777(線段樹 標記 狀態壓縮)

2021-07-04 02:51:35 字數 1566 閱讀 3153

題目鏈結》
題目大意:給你乙個長為l的板,然後給上邊的每一段塗顏色, 給出一系列操作對應更新區間或輸出該區間有多少中顏色, 本題肯定能想到線段樹來解決,然後根據t<30想到用狀態 壓縮的方法,用位運算同時也要加上lazy標記,不然很容 易超時。

注意異或^的用法 x ^ (1 << (k - 1)) = 0 表示x的第k位(從 k = 1 開始)為1否則為0。

第一次寫這方面的題,寫的又長又醜,搞得我 挖了一發就不想再看自己寫的**了,而且本題 要注意所給的區間a到b可能a

#include 

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn = 100000 + 5;

int flag;

struct node ;

node tree[maxn*4];

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

int mid = (l+r) >> 1;

build(p<<1, l, mid);

build(p<<1|1, mid+1, r);

tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;

}void push_down(int p, int l, int r, int z)

if ((rr.lazy^(1

<<(z-1))) != 0)

}void change(int p, int l, int r, int x, int y, int z)

return;

}for (int i = 0; i < 31; i++)

}int mid = (l+r)>>1;

if (x <= mid) change(p<<1, l, mid, x, y, z);

if (y > mid) change(p<<1|1, mid+1, r, x, y, z);

tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;

}int query(int p, int l ,int r, int x, int y)

for (int i = 0; i < 31; i++)

}int mid = (l+r)>>1;

int ans = 0;

if (x <= mid) ans = ans|query(p<<1, l, mid, x, y);

if (y > mid) ans = ans|query(p<<1|1, mid+1, r, x, y);

tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;

return ans;

}int main()

else

}return

0;}

線段樹模板 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線段樹,狀態壓縮

題意 就是一堆石頭,開始全是一種顏色 之後叫你染色,顏色不超過30種 染色的規則是一段一段染 叫你求某一段區間的顏色種數 理解 這題一看就是線段樹 主要就是記錄顏色的問題 開始我以為是線段樹區間合併的問題 結果經過師兄師姐的薰陶 發現果然是狀態壓縮 就是用數字記錄顏色的種數 因為不超過30種,所以用...