zoukankan      html  css  js  c++  java
  • BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

    2243: [SDOI2011]染色

    Description

     

    给定一棵有n个节点的无根树和m个操作,操作有2类:

    1、将节点a到节点b路径上所有点都染成颜色c;

    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”3段组成:“11”、“222”和“1”

    请你写一个程序依次完成这m个操作。

    Input

    第一行包含2个整数n和m,分别表示节点数和操作数;

    第二行包含n个正整数表示n个节点的初始颜色

    下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

    下面 行每行描述一个操作:

    “C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

    “Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

     

    Output

    对于每个询问操作,输出一行答案。

     

    Sample Input

    6 5

    2 2 1 2 1 1

    1 2

    1 3

    2 4

    2 5

    2 6

    Q 3 5

    C 2 1 1

    Q 3 5

    C 5 1 2

    Q 3 5

    Sample Output

    3

    1

    2

    HINT

    数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

    题解:

      树链剖分后,在相应的标号上进行线段树操作

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 5e5+10, M = 1e3+20, mod = 1e9+7, inf = 2e9;
    
    int dep[N],head[N],t=1,sz[N],fa[N],indexS,top[N],pos[N];
    struct ss{int to,next;}e[N*2];
    int n;
    void add(int u,int v)
    {e[t].to = v;e[t].next = head[u];head[u] = t++;}
    
    void dfs(int u) {
        sz[u] = 1;
        dep[u] = dep[fa[u]] + 1;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(to == fa[u]) continue;
            fa[to] = u;
            dfs(to);
            sz[u] += sz[to];
        }
    }
    void dfs(int u,int chain) {
        int k = 0;
        pos[u] = ++indexS;
        top[u] = chain;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(dep[to] > dep[u] && sz[to] > sz[k])
                k = to;
        }
        if(k == 0) return ;
        dfs(k,chain);
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(dep[to] > dep[u] && k != to)
                dfs(to,to);
        }
    }
    
    LL lx[N],rx[N],mx[N],sum[N],lazy[N],fposs[N];
    void push_up(int i) {
        sum[i] = sum[ls] + sum[rs];
        if(rx[ls] == lx[rs]) sum[i]-=1;
        lx[i] = lx[ls];rx[i] = rx[rs];
    }
    void build(int i,int ll,int rr) {
        if(ll == rr) {
            lx[i] = fposs[ll];
            rx[i] = fposs[ll];
            sum[i] = 1;
            return ;
        }
        build(ls,ll,mid),build(rs,mid+1,rr);
        push_up(i);
    }
    void push_down(int i,int ll,int rr) {
        if(lazy[i] && ll != rr) {
            lazy[ls] = lazy[i];
            lazy[rs] = lazy[i];
            lx[ls] = lazy[i];
            rx[ls] = lazy[i];
            lx[rs] = lazy[i];
            rx[rs] = lazy[i];
            sum[ls] = 1;
            sum[rs] = 1;
            lazy[i] = 0;
        }
    }
    void update(int i,int ll,int rr,int x,int y,int c) {
        push_down(i,ll,rr);
        if(ll == x && rr == y) {
            lazy[i] = c;
            lx[i] = c;
            rx[i] = c;
            sum[i] = 1;
            return ;
        }
        if(y <= mid) update(ls,ll,mid,x,y,c);
        else if(x > mid) update(rs,mid+1,rr,x,y,c);
        else {
            update(ls,ll,mid,x,mid,c);
            update(rs,mid+1,rr,mid+1,y,c);
        }
        push_up(i);
    }
    void change(int x,int y,int c) {
        while(top[x] != top[y]) {
            if(dep[top[x]] < dep[top[y]]) swap(x,y);
            update(1,1,n,pos[top[x]],pos[x],c);
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        update(1,1,n,pos[x],pos[y],c);
    }
    int query(int i,int ll,int rr,int x,int y) {
       push_down(i,ll,rr);
        if(ll == x && rr == y) return sum[i];
        if(y <= mid) return query(ls,ll,mid,x,y);
        else if(x > mid) return query(rs,mid+1,rr,x,y);
        else return (query(ls,ll,mid,x,mid) + query(rs,mid+1,rr,mid+1,y) - (lx[rs] == rx[ls]));
        push_up(i);
    }
    int color(int i,int ll,int rr,int x) {
        push_down(i,ll,rr);
        if(ll == rr) return lx[i];
        if(x <= mid) return color(ls,ll,mid,x);
        else return color(rs,mid+1,rr,x);
        push_up(i);
    }
    int query(int x,int y) {
        int res = 0,lastx = -1,lasty = -1;
        while(top[x] != top[y]) {
            if(dep[top[x]] > dep[top[y]]) {
                res += query(1,1,n,pos[top[x]],pos[x]);
                if(color(1,1,n,pos[x]) == lastx) res--;
                lastx = color(1,1,n,pos[top[x]]);
                x = fa[top[x]];
            }
            else {
                res += query(1,1,n,pos[top[y]],pos[y]);
                if(color(1,1,n,pos[y]) == lasty) res--;
                lasty = color(1,1,n,pos[top[y]]);
                y = fa[top[y]];
            }
        }
        if(dep[x] < dep[y])res += query(1,1,n,pos[x],pos[y]);
        else res += query(1,1,n,pos[y],pos[x]);
        if(color(1,1,n,pos[x]) == lastx) res--;
        if(color(1,1,n,pos[y]) == lasty) res--;
        return res;
    }
    int Q,a[N],x,y;
    char ch[N];
    int main() {
        scanf("%d%d",&n,&Q);
        for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
        for(int i = 1; i < n; ++i) {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1);
        dfs(1,1);
        for(int i = 1; i <= n; ++i) fposs[pos[i]] = a[i];
        build(1,1,n);
        while(Q--) {
            int a,b,c;
            scanf("%s",ch);
            if(ch[0] == 'Q') {
                scanf("%d%d",&a,&b);
                printf("%d
    ",query(a,b));
            }else {
                scanf("%d%d%d",&a,&b,&c);
                change(a,b,c);
            }
        }
        return 0;
    }
    
    /*
    6 5
    2 2 1 2 1 1
    1 2
    1 3
    2 4
    2 5
    2 6
    Q 3 5
    C 2 1 1
    Q 3 5
    C 5 1 2
    Q 3 5
    */
  • 相关阅读:
    JavaScript常用正則表達式
    详尽解析window.event对象
    DWR的类却无法在js里用
    javascript控制小数点精度
    49. Group Anagrams
    48. Rotate Image
    64. Minimum Path Sum
    63. Unique Paths II
    62. Unique Paths
    53. Maximum Subarray
  • 原文地址:https://www.cnblogs.com/zxhl/p/5239922.html
Copyright © 2011-2022 走看看