HYSBZ 2243-染色 (树链剖分)
1A!!! 哈哈哈哈哈没看题解 没套模板哈哈哈哈 太感动了!!
如果只是线段树的话这道题倒是不难,只要记录左右边界就好了,类似很久以前做的hotel的题
但是树上相邻的段会有连续的
树上top[x]和fa[top[x]]是连续的,但是线段树上是算不到的,所以要判断下
线段树记录的是区间的数量,但是求单点的时候求得是颜色,需要注意下
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 100005; int a[N]; struct Edge { int to, next; } edge[N*2]; int head[N], cntE; void addedge(int u, int v) { edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++; edge[cntE].to = u; edge[cntE].next = head[v]; head[v] = cntE++; } int dep[N], fa[N], sz[N], son[N]; void dfs1(int u, int pre, int d) { dep[u] = d; sz[u] = 1; fa[u] = pre; for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (v != pre) { dfs1(v, u, d+1); sz[u] += sz[v]; if (son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v; } } } int top[N], dfn[N], rk[N], idx; void dfs2(int u, int tp) { top[u] = tp; dfn[u] = ++idx; rk[idx] = u; if (son[u] == -1) return ; dfs2(son[u], tp); for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (v != fa[u] && v != son[u]) { dfs2(v, v); } } } int tr[N<<2], ltr[N<<2], rtr[N<<2]; // tr[i] means the number of color segment int fg[N<<2]; #define lson o<<1 #define rson o<<1|1 void pushup(int o) { ltr[o] = ltr[lson]; rtr[o] = rtr[rson]; tr[o] = tr[lson] + tr[rson]; if (rtr[lson] == ltr[rson]) tr[o]--; } void pushdown(int o) { if (fg[o]) { tr[lson] = tr[rson] = 1; fg[lson] = fg[rson] = fg[o]; ltr[lson] = ltr[rson] = ltr[o]; rtr[lson] = rtr[rson] = rtr[o]; fg[o] = 0; } } void build(int o, int l, int r) { fg[o] = 0; if (l == r) { tr[o] = 1; ltr[o] = rtr[o] = a[rk[l]]; return; } int mid = (l+r) >> 1; build(lson, l, mid); build(rson, mid+1, r); pushup(o); } void change(int o, int l, int r, int L, int R, int v) { if (l >= L && r <= R) { fg[o] = 1; tr[o] = 1; ltr[o] = rtr[o] = v; return ; } pushdown(o); int mid = (l+r) >> 1; if (mid >= L) change(lson, l, mid, L, R, v); if (mid < R) change(rson, mid+1, r, L, R, v); pushup(o); } void CHANGE(int x, int y, int n, int c) { while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); change(1, 1, n, dfn[top[x]], dfn[x], c); x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); change(1, 1, n, dfn[x], dfn[y], c); } int query(int o, int l, int r, int L, int R) { if (l >= L && r <= R) return tr[o]; pushdown(o); int mid = (l+r) >> 1; if (mid < L) { return query(rson, mid+1, r, L, R); } else if (mid >= R) { return query(lson, l, mid, L, R); } else { int ans = query(lson, l, mid, L, R); ans += query(rson, mid+1, r, L, R); if (ltr[rson] == rtr[lson]) ans--; return ans; } } int qq(int o, int l, int r, int p) { if (l == r) return ltr[o]; pushdown(o); int mid = (l+r) >> 1; if (mid >= p) return qq(lson, l, mid, p); return qq(rson, mid+1, r, p); } int QUERY(int x, int y, int n) { int ans = 0; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); ans += query(1, 1, n, dfn[top[x]], dfn[x]); if (qq(1, 1, n, dfn[top[x]]) == qq(1, 1, n, dfn[fa[top[x]]])) --ans; x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); ans += query(1, 1, n, dfn[x], dfn[y]); return ans; } void init() { memset(head, -1, sizeof head); memset(son, -1, sizeof son); idx = cntE = 0; } int main() { //freopen("in.txt", "r", stdin); int n, m; while (~scanf("%d%d", &n, &m)) { init(); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); int u, v, c; for (int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); addedge(u, v); } dfs1(1, 0, 0); dfs2(1, 1); build(1, 1, n); char op[10]; while (m--) { scanf("%s", op); if (*op == 'Q') { scanf("%d%d", &u, &v); printf("%d\n", QUERY(u, v, n)); } else { scanf("%d%d%d", &u, &v, &c); CHANGE(u, v, n, c); } } } return 0; }
分类:
ACM/算法/数据结构
标签:
树链剖分
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2015-10-02 UVALive 5111 Soccer Teams (动态规划)