题目描述
思路
尽量不要直接使用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; }