BZOJ2243——[SDOI2011]染色

来源:互联网 发布:python for in循环 编辑:程序博客网 时间:2024/05/20 17:39
1、题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段
2、分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建线段树吗
我们的线段树存这样的几个值,一个是这个区间被分成了几段,另外就是这个区间的最左边的颜色和最右边的颜色
这样,我们在区间合并的时候把两个区间的段数加起来

然后用左区间的右端点和右区间的左端点如果相同就-1就可以了,那么这道题就做完了

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define M 1000000struct node{    int l, ans, r;};struct hehe{    int Top[M], Size[M], High[M], Fa[M], num[M], value[M];    node q[M];    int lazy[M];    int tot, head[M], Next[M], son[M];    int ST_tot;    int n;    inline void init(){        ST_tot = tot = 0;        for(int i = 1; i < M; i ++) lazy[i] = -1;        memset(head, -1, sizeof(head));        Top[1] = 1;    }    inline void pushdown(int o){        if(lazy[o] != -1){            lazy[2 * o] = lazy[2 * o + 1] = lazy[o];            q[2 * o].l = q[2 * o].r = q[2 * o + 1].l = q[2 * o + 1].r = lazy[o];            q[2 * o].ans = q[2 * o + 1].ans = 1;            lazy[o] = -1;        }    }    inline void add(int l, int r, int o, int x, int y, int k){        if(x <= l && r <= y){            q[o].l = q[o].r = k;            q[o].ans = 1;            lazy[o] = k;            return;        }        int mid = (l + r) / 2;        pushdown(o);        if(x <= mid) add(l, mid, 2 * o, x, y, k);        if(y > mid) add(mid + 1, r, 2 * o + 1, x, y, k);        q[o].l = q[2 * o].l;        q[o].r = q[2 * o + 1].r;        q[o].ans = q[2 * o].ans + q[2 * o + 1].ans;        if(q[2 * o].r == q[2 * o + 1].l) q[o].ans --;    }    inline node query(int l, int r, int o, int x, int y){        if(x <= l && r <= y){            return q[o];        }        pushdown(o);        int mid = (l + r) / 2;        if(x <= mid && y <= mid) return query(l, mid, 2 * o, x, y);        else if(x > mid && y > mid) return query(mid + 1, r, 2 * o + 1, x, y);        else{            node ll = query(l, mid, 2 * o, x, y);            node rr = query(mid + 1, r, 2 * o + 1, x, y);            node ret;            ret.l = ll.l;            ret.r = rr.r;            ret.ans = ll.ans + rr.ans;            if(ll.r == rr. l) ret.ans --;            return ret;        }     }    inline void insert(int x, int y){        tot ++;        son[tot] = y;        Next[tot] = head[x];        head[x] = tot;    }    inline void dfs1(int x, int fa, int height){        Fa[x] = fa;        High[x] = height;        for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){            dfs1(son[i], x, height + 1);            Size[x] += Size[son[i]];        }        Size[x] ++;    }    inline void dfs2(int x, int fa){        ++ ST_tot;        num[x] = ST_tot;        add(1, n, 1, ST_tot, ST_tot, value[x]);        int o = -1, sos = 0;        for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){            if(Size[son[i]] > sos){                sos = Size[son[i]];                o = i;            }        }        if(o != -1){            Top[son[o]] = Top[x];            dfs2(son[o], x);        }        for(int i = head[x]; i != -1; i = Next[i]) if(son[i] != fa && i != o){            Top[son[i]] = son[i];            dfs2(son[i], x);        }    }    inline void real_add(int x, int y, int k){        while(Top[x] != Top[y]){            if(High[Top[x]] < High[Top[y]]) swap(x, y);            add(1, n, 1, num[Top[x]], num[x], k);            x = Fa[Top[x]];        }            if(High[x] < High[y]) swap(x, y);        add(1, n, 1, num[y], num[x], k);        return;    }    inline int real_query(int x, int y){        int tx = -1, ty = -1;        int ret = 0;        while(Top[x] != Top[y]){            if(High[Top[x]] < High[Top[y]]){                swap(x, y);                swap(tx, ty);            }            node hh = query(1, n, 1, num[Top[x]], num[x]);            ret += hh.ans;            if(hh.r == tx) ret --;            tx = hh.l;            x = Fa[Top[x]];        }        if(High[x] < High[y]){            swap(x, y);            swap(tx, ty);        }        node hh = query(1, n, 1, num[y], num[x]);        ret += hh.ans;        if(hh.r == tx) ret --;        if(hh.l == ty) ret --;        return ret;    }} wt;int main(){    int n, m;    scanf("%d%d", &n, &m);    wt.n = n;    wt.init();    for(int i = 1; i <= n; i ++) scanf("%d", &wt.value[i]);    for(int i = 1; i < n; i ++){        int x, y;        scanf("%d%d", &x, &y);        wt.insert(x, y);        wt.insert(y, x);    }    wt.dfs1(1, -1, 1);    wt.dfs2(1, -1);    char str[2];    int x, y, z;    for(int i = 1; i <= m; i ++){        scanf("%s", str);        if(str[0] == 'Q'){            scanf("%d%d", &x, &y);            printf("%d\n", wt.real_query(x, y));        }        else{            scanf("%d%d%d", &x, &y, &z);            wt.real_add(x, y, z);        }    }    return 0;}


0 0