一  题目

  [SDOI2011]染色

二 分析

  感觉树链剖分的这些题真的蛮考验码力的,自己的码力还是不够啊!o(╯□╰)o

  还是比较常规的树链剖分,但是一定记得这里的线段树在查询的时候一定要考虑链于链相邻的两个点。

  一开始自己已经把很多坑都已经注意了,包括颜色可以为0,链的相邻点,但怎么就是不正确,还是要多刷题。

三 AC代码

  1 /**************************************************************
  2     Problem: 2243
  3     User: Dybala21
  4     Language: C++
  5     Result: Accepted
  6     Time:6652 ms
  7     Memory:18580 kb
  8 ****************************************************************/
  9
 10 #include <bits/stdc++.h>
 11 using namespace std;
 12 const int MAXN = 1e5 + 15;
 13 int n, m;
 14 int c[MAXN];
 15 struct Edge
 16 {
 17     int to, next;
 18 }edge[MAXN<<1];
 19 int head[MAXN], tot;
 20 int e[MAXN][2];
 21 int fa[MAXN], deep[MAXN], sz[MAXN], son[MAXN];
 22 int p[MAXN], top[MAXN];
 23 int pos;
 24
 25 void init()
 26 {
 27     tot = 0, pos = 0;
 28     memset(head, -1, sizeof(head));
 29     memset(son, -1, sizeof(son));
 30 }
 31 void addedge(int u, int v)
 32 {
 33     edge[tot].to = v;
 34     edge[tot].next = head[u];
 35     head[u] = tot++;
 36 }
 37 void dfs1(int u, int pre, int d)
 38 {
 39     fa[u] = pre;
 40     sz[u] = 1;
 41     deep[u] = d;
 42     for(int i = head[u]; i != -1; i = edge[i].next)
 43     {
 44         int v = edge[i].to;
 45         if(v != pre)
 46         {
 47             dfs1(v, u, d + 1);
 48             sz[u] += sz[v];
 49             if(son[u] == -1 || sz[v] > sz[son[u]])
 50                 son[u] = v;
 51         }
 52     }
 53 }
 54 void dfs2(int u, int sp)
 55 {
 56     p[u] = ++pos;
 57     top[u] = sp;
 58     if(son[u] != -1)
 59         dfs2(son[u], sp);
 60     else
 61         return;
 62     for(int i = head[u]; i != -1; i = edge[i].next)
 63     {
 64         int v = edge[i].to;
 65         if(v != fa[u] && v != son[u])
 66             dfs2(v, v);
 67     }
 68 }
 69 int lca(int x, int y)
 70 {
 71     int f1 = top[x], f2 = top[y];
 72     while(f1 != f2)
 73     {
 74
 75         if(deep[f1] < deep[f2])
 76         {
 77             swap(f1, f2);
 78             swap(x, y);
 79         }
 80         x = fa[f1];
 81         f1 = top[x];
 82     }
 83     if(deep[x] < deep[y])   swap(x, y);
 84     return y;
 85 }
 86 struct Node
 87 {
 88     int l, r;
 89     int lc, rc;
 90     int lazy, sum;
 91 }segTree[MAXN*3];
 92 void pushdown(int rt)
 93 {
 94     int tmp = segTree[rt].lazy;
 95     segTree[rt].lazy = -1;
 96     if(tmp == -1 || segTree[rt].l == segTree[rt].r)
 97         return;
 98     segTree[rt<<1].lc = segTree[rt<<1].rc = tmp;
 99     segTree[rt<<1|1].lc = segTree[rt<<1|1].rc = tmp;
100     segTree[rt<<1].sum = segTree[rt<<1|1].sum = 1;
101     segTree[rt<<1].lazy = segTree[rt<<1|1].lazy = tmp;
102 }
103 void maintain(int rt)
104 {
105     segTree[rt].sum = segTree[rt<<1].sum + segTree[rt<<1|1].sum;
106     if(segTree[rt<<1].rc == segTree[rt<<1|1].lc)
107         segTree[rt].sum--;
108     segTree[rt].lc = segTree[rt<<1].lc;
109     segTree[rt].rc = segTree[rt<<1|1].rc;
110 }
111 void build(int rt, int l, int r)
112 {
113     segTree[rt].l = l;
114     segTree[rt].r = r;
115     segTree[rt].lazy = -1;
116     segTree[rt].sum = 0;
117     if(l == r)
118         return;
119     int mid = (l + r) >> 1;
120     build(rt<<1, l, mid);
121     build(rt<<1|1, mid + 1, r);
122 }
123 void update(int rt, int l, int r, int val)
124 {
125     pushdown(rt);
126     if(segTree[rt].l == l && segTree[rt].r == r)
127     {
128         segTree[rt].lazy = val;
129         segTree[rt].lc = segTree[rt].rc = val;
130         segTree[rt].sum = 1;
131         return;
132     }
133     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
134     if(r <= mid)
135         update(rt<<1, l, r, val);
136     else if(l > mid)
137         update(rt<<1|1, l, r, val);
138     else
139     {
140         update(rt<<1, l, mid, val);
141         update(rt<<1|1, mid+1, r, val);
142     }
143     maintain(rt);
144 }
145 void update(int x, int y, int val)
146 {
147     while(top[x] != top[y])
148     {
149         if(deep[top[x]] < deep[top[y]])
150             swap(x, y);
151         update(1, p[top[x]], p[x], val);
152         x = fa[top[x]];
153     }
154     if(deep[x] < deep[y])
155         swap(x, y);
156     update(1, p[y], p[x], val);
157 }
158 int query(int rt, int l, int r)
159 {
160     pushdown(rt);
161     if(segTree[rt].l == l && segTree[rt].r == r)
162         return segTree[rt].sum;
163     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
164     int ans = 0;
165     if(r <= mid)
166         ans += query(rt<<1, l, r);
167     else if(l > mid)
168         ans += query(rt<<1|1, l, r);
169     else
170     {
171         ans += query(rt<<1, l, mid);
172         ans += query(rt<<1|1, mid + 1, r);
173         if(segTree[rt<<1].rc == segTree[rt<<1|1].lc)
174             ans--;
175     }
176     return ans;
177 }
178 int find(int rt, int x)
179 {
180     pushdown(rt);
181     if(segTree[rt].l == segTree[rt].r)
182         return segTree[rt].lc;
183     int mid = (segTree[rt].l + segTree[rt].r) >> 1;
184     if(x <= mid)
185         return find(rt<<1, x);
186     else
187         return find(rt<<1|1, x);
188 }
189 int query(int x, int y)
190 {
191     int res = 0;
192     while(top[x] != top[y])
193     {
194         if(deep[top[x]] < deep[top[y]])
195             swap(x, y);
196         res += query(1, p[top[x]], p[x]);
197         if(find(1, p[top[x]]) == find(1, p[fa[top[x]]]))
198             res--;
199         x = fa[top[x]];
200     }
201     if(deep[x] < deep[y])
202         swap(x, y);
203     res += query(1, p[y], p[x]);
204     return res;
205 }
206 int main()
207 {
208     //freopen("in.txt", "r", stdin);
209     init();
210     scanf("%d%d", &n, &m);
211     for(int i = 1; i <= n; i++)
212         scanf("%d", &c[i]);
213     for(int i = 0; i < n - 1; i++)
214     {
215         scanf("%d%d", &e[i][0], &e[i][1]);
216         addedge(e[i][0], e[i][1]);
217         addedge(e[i][1], e[i][0]);
218     }
219     dfs1(1, 1, 1);
220     dfs2(1, 1);
221     build(1, 1, pos);
222     for(int i = 1; i <= n; i++)
223         update(1, p[i], p[i], c[i]);
224     char op;
225     int a, b, val;
226     for(int i = 0; i < m; i++)
227     {
228         scanf(" %c %d %d", &op, &a, &b);
229         if(op == 'Q')
230         {
231             printf("%d\n", query(a, b));
232         }
233         else
234         {
235             scanf("%d", &val);
236             update(a, b, val);
237         }
238     }
239     return 0;
240 }
241 

转载于:https://www.cnblogs.com/dybala21/p/10850691.html

BZOJ_2243 [SDOI2011]染色 【树链剖分+线段树】相关推荐

  1. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  2. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 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. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  4. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  5. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  6. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  7. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. 理解Java字符串常量池与intern()方法
  2. [转]sleep和wait有什么区别
  3. Locations Section of OpenCascade BRep
  4. screen 断开 screen -r 不能进入断开的会话
  5. 程序员面试金典 - 面试题 05.01. 插入(位运算)
  6. android 页面无法点击,为什么点击不跳转到下一界面,哪位大神帮瞅瞅
  7. TensorFlow tf.feature_column
  8. 【渝粤教育】电大中专工程图学基础_1作业 题库
  9. TeaVM当前版本(0.7.0)还不支持传递字串参数
  10. LaTex笔记二:visio画图并保存为eps格式
  11. coreos_CoreOS简介
  12. Gmail邮件客户端pop3和smtp服务器配置
  13. C++11 std::mutex使用以及std::lock_guard自动解锁避免忘记解锁
  14. 复数基础——负数的虚数根,复共轭,复数加法、减法、乘法、除法_6
  15. 800个有趣句子帮你记忆7000个单词(1-400)
  16. linux下设置共享目录
  17. 2020 JAVA eclipse 中文汉化包 安装教程--傻瓜式操作
  18. sstream和strstream的用法
  19. scroll-view的描点跳转
  20. J - 【黄色】这题真的是模板题 (Gym - 102072J )(spfa)

热门文章

  1. Ubuntu 下 matplotlib 中文乱码
  2. MySQL只有.frm文件恢复表结构
  3. SonicWALL防火墙初探
  4. [SQl读书笔记]§6.Transact-SQL(4)
  5. 鸿蒙 HarmonyOS 3.0,终于来了!
  6. B 站 CEO 的身份证被上传到 GitHub 了?这个火了
  7. 推荐一个滴滴开源的跨端整体解决方案!
  8. 推荐一波对你来说,非常有用的网站,记得收藏
  9. 我私藏的一个超级无敌好用的 Java 工具类库
  10. 为什么领导们总是劝大家不要只盯着工资?