线段树2 POJ2777 Count Color

来源:互联网 发布:百度糯米提示无网络 编辑:程序博客网 时间:2024/05/18 03:12

http://poj.org/problem?id=2777

#include <stdio.h>#include <memory.h>#define LCH(a) ((a)<<1)#define RCH(a) (((a)<<1)+1)#define NO_COLOR 0typedef 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;}


原创粉丝点击