題目鏈結》
題目大意:給你乙個長為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種,所以用...