http://poj.org/problem?id=2777
#include
#include
#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;
}