線段樹2 POJ2777 Count Color
阿新 • • 發佈:2019-01-24
#include <stdio.h> #include <memory.h> #define LCH(a) ((a)<<1) #define RCH(a) (((a)<<1)+1) #define NO_COLOR 0 typedef struct nodetag{int st, ed, value;} node; node valtree[400000]; int l,t,o; void init(int place, int st, int ed) { int mid = (st + ed)/2; valtree[place].st = st; valtree[place].ed = ed; valtree[place].value = 1; if(st < ed){ init(LCH(place), st, mid); init(RCH(place), mid+1, ed); } } void change (int place, int st, int ed, int color) { int mid = (valtree[place].st + valtree[place].ed)/2; if(valtree[place].st == st && valtree[place].ed == ed){valtree[place].value = color;} else{ if(valtree[place].value != NO_COLOR)// 假使color == valtree[place].value如何? { change(LCH(place), valtree[place].st, mid, valtree[place].value); change(RCH(place), mid+1, valtree[place].ed, valtree[place].value); } valtree[place].value = NO_COLOR; if(mid + 1 <= st) change(RCH(place), st, ed, color); else if(ed <= mid) change(LCH(place), st, ed, color); else{ change(LCH(place), st, mid, color); change(RCH(place), mid+1, ed, color); } } } /* change 邏輯是有問題的。沒有保持迴圈不變數。 假使row3: else color == valtree[place].value, 。。。I 雖然左右子樹的根結點被塗成父結點顏色,且僅迭代一次就因為row2 線段重合返回, 但是此時父結點被塗成了無色,事實上其應該還是color顏色。所幸通過view計數時,父結點雖然沒計數,但是會通過左右兒子結點彌補。 當I不成立時,沒有問題,邏輯同change2 e.gchange(1,2,2,color),查詢這個葉子結點的一路上都會被標記成NO_COLOR */ void change2(int place ,int st, int ed, int color) { if(valtree[place].value == color) return; int mid = (valtree[place].st + valtree[place].ed) / 2; if(valtree[place].st == st && valtree[place].ed == ed) valtree[place].value = color; else{ if(valtree[place].value != NO_COLOR) { valtree[LCH(place)].value = valtree[place].value; valtree[RCH(place)].value = valtree[place].value; valtree[place].value = NO_COLOR; } if(mid+1<=st) change(RCH(place), st, ed, color); else if(ed <= mid) change(LCH(place), st, ed, color); else { change(LCH(place), st, mid, color); change(RCH(place), mid+1, ed, color); } } } int ans; char color[40]; void newcolor(int a) { if(!color[a]){ color[a] = 1; ans++; } } void view(int place, int st, int ed)//supports st > ed { int mid = (valtree[place].st + valtree[place].ed)/2; if(valtree[place].value != NO_COLOR){newcolor(valtree[place].value);} else{ if(ed <= mid) view(LCH(place), st, ed); else if(st >= mid+1) view(RCH(place), st, ed); else { view(LCH(place), st, mid); view(RCH(place), mid+1, ed); } } } void view2(int place, int st, int ed) // must st <= ed 不如view好 { int mid = (valtree[place].st + valtree[place].ed) / 2; if(valtree[place].value != NO_COLOR) newcolor(valtree[place].value); else if(ed >= st){ if(ed <= mid) view(LCH(place), st, ed); else if(st >= mid+1) view(RCH(place), st, ed); else{ view(LCH(place), st, mid); view(RCH(place), mid+1, ed); } } } /* 2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2 */ void exchange(int &a, int &b){ int tmp = a; a = b; b = a;} int main() { int i, a,b,c; char op[2]; scanf("%d%d%d", &l, &t, &o); init(1, 1, l); for(i = 0; i < o; ++i) { scanf("%s", op); if(op[0] == 'C'){ scanf("%d%d%d", &a, &b, &c); if(a > b) exchange(a, b); change2(1, a, b, c); }else if(op[0] == 'P'){ scanf("%d%d", &a, &b); ans = 0; memset(color, 0, sizeof(color)); view(1, a, b); //if(a>b) exchange(a, b); //view2(1, a, b); printf("%d\n", ans); } } return 0; }