zoukankan      html  css  js  c++  java
  • 染色

    题目描述

    思路

    尽量不要直接使用getchar得到单个字符,容易出现runtime error, 可以使用scanf("%s", str), 直接判断str[0]是否是对应字符就可以了。

    代码

    #include <cstdio>
    #include <cstring>
    #define lc k<<1
    #define rc k<<1|1
    
    const int MAX = 100100;
    int n, m, wt[MAX], ans;
    int head[MAX], ver[MAX << 1], nt[MAX << 1], ht;
    int fa[MAX], size[MAX], son[MAX], dep[MAX];
    int top[MAX], dfn[MAX], tr[MAX], dt;
    int lg[MAX << 2], rg[MAX << 2], sum[MAX << 2];
    bool fg[MAX << 2];
    char str[100];
    
    int read() {
        int s = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            s = s * 10 + ch - '0'; ch = getchar();
        }
        return s * f;
    }
    void write(int x) {
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
    
    void add(int x, int y) {
        nt[++ht] = head[x], head[x] = ht, ver[ht] = y;
    }
    
    void dfs1(int x, int u) {
        fa[x] = u;
        dep[x] = dep[u] + 1;
        size[x] = 1;
        for (int i = head[x], j; j = ver[i]; i = nt[i]) {
            if (j == u) continue;
            dfs1(j, x);
            size[x] += size[j];
            if (size[j] > size[son[x]]) son[x] = j;
        }
    }
    
    void dfs2(int x, int u) {
        top[x] = u;
        dfn[x] = ++dt;
        tr[dt] = x;
        if (son[x]) dfs2(son[x], u);
        for (int i = head[x], j; j = ver[i]; i = nt[i]) {
            if (!dfn[j]) dfs2(j, j);
        }
    }
    void pushup(int k, int l, int r) {
        lg[k] = lg[lc], rg[k] = rg[rc];
        sum[k] = sum[lc] + sum[rc];
        if (rg[lc] == lg[rc]) sum[k]--;  
    }
    
    void pushdown(int k, int l, int r, int mid) {
        if (!fg[k]) return;
        fg[lc] = fg[rc] = true;
        sum[lc] = sum[rc] = 1;
        lg[lc] = lg[rc] = rg[lc] = rg[rc] = lg[k];
        fg[k] = false;
    }
    
    void swap(int &x, int &y) {
        int t = x;
        x = y, y = t;
    }
    
    void build(int k, int l, int r) {
        if (l == r) {
            lg[k] = rg[k] = wt[tr[l]];
            sum[k] = 1;
            return;
        }
        int mid = l + r >> 1;
        build(lc, l, mid);
        build(rc, mid + 1, r);
        pushup(k, l, r);
    }
    
    int getColor(int k, int l, int r, int x) {
        if (l == r && x == l) return lg[k];
        int mid = l + r >> 1;
        pushdown(k, l, r, mid);
        if (x <= mid) return getColor(lc, l, mid, x);
        else return getColor(rc, mid + 1, r, x);
    }
    
    void change(int k, int l, int r, int x, int y, int z) {
        if (x <= l && r <= y) {
            fg[k] = true;
            sum[k] = 1;
            lg[k] = rg[k] = z;
            return;
        }
        int mid = l + r >> 1;
        pushdown(k, l, r, mid);
        if (x <= mid) change(lc, l, mid, x, y, z);
        if (y > mid) change(rc, mid + 1, r, x, y, z);
        pushup(k, l, r);
    }
    
    void query(int k, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
            ans += sum[k];
            return;
        }
        int mid = l + r >> 1;
        pushdown(k, l, r, mid);
        if (x <= mid) query(lc, l, mid, x, y);
        if (y > mid) query(rc, mid + 1, r, x, y);
        if (x <= mid && y > mid && rg[lc] == lg[rc]) ans--;
    }
    
    void ask(int x, int y) {
        int fx = top[x], fy = top[y];
        while (fx != fy) {
            if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
            query(1, 1, n, dfn[fx], dfn[x]);
            if (getColor(1, 1, n, dfn[fx]) == getColor(1, 1, n, dfn[fa[fx]])) ans--;
            x = fa[fx], fx = top[x];
        }
        if (dep[x] > dep[y]) swap(x, y);
        query(1, 1, n, dfn[x], dfn[y]);
    }
    
    void askChange(int x, int y, int z) {
        int fx = top[x], fy = top[y];
        while (fx != fy) {
            if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
            change(1, 1, n, dfn[fx], dfn[x], z);
            x = fa[fx], fx = top[x];
        }
        if (dep[x] > dep[y]) swap(x, y);
        change(1, 1, n, dfn[x], dfn[y], z);
    }
    
    int main() {
        n = read(), m = read();
        for (int i = 1; i <= n; ++i) wt[i] = read();
        for (int i = 1, a, b; i < n; ++i) {
            a = read(), b = read();
            add(a, b), add(b, a);
        }
        dfs1(1, 0);
        dfs2(1, 1);
        build(1, 1, n);
        for (int i = 1, j, a, b, c; i <= m; ++i) {
            scanf("%s", str);
            if (str[0] == 'Q') {
                a = read(), b = read();
                ans = 0;
                ask(a, b);
                write(ans);
                puts(""); 
            } else {
                a = read(), b = read(), c = read();
                askChange(a, b, c);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    C# List转换成DataTable
    表达式计算
    通过GitHub高级条件组合精确搜索开源项目学习
    今天开通博客啦 随便记录一下东西
    VSCode开发Vue-代码格式化最完美设置
    C# DataTable 行转列 列转行 同时转换
    [转载]DevExpress GridControl 使用方法技巧 总结 收录整理
    控件已成功添加到工具箱中,但未在活动设计器中启用
    js-beautify 不换行
    tomcat端口修改后在Eclipse中启动无效问题解决
  • 原文地址:https://www.cnblogs.com/liuzz-20180701/p/11536712.html
Copyright © 2011-2022 走看看