传送门

这题卡常……而且目前还没有卡过去

首先以原树重心为根,向所有子树重心连边,可以建立一棵点分树

点分树有两个性质:

一个是树高只有log层

另一个是两点在点分树上的lca一定在原树上两点间的树上路径上

所以在原树上不断删点,并统计当前子树中的信息就好

至于如何统计,令 \(dp[i][j][k][l]\) 表示分治中心为 \(i\) ,到点 \(j\) ,第一条边颜色为 \(k\) ,最后一条边颜色为 \(j\) 的最大得分

转移挺好写的,询问时暴力枚举相关连边的颜色

留个坑,纯点分治还不会写呢

Code:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define INF 0x3f3f3f3f
  4. #define N 100010
  5. #define ll long long
  6. #define reg register int
  7. #define fir first
  8. #define sec second
  9. #define make make_pair
  10. #define pb push_back
  11. #define min2(a, b) ((a)<(b)?(a):(b))
  12. #define max2(a, b) ((a)>(b)?(a):(b))
  13. //#define int long long
  14. char buf[1<<21], *p1=buf, *p2=buf;
  15. #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
  16. inline int read() {
  17. int ans=0, f=1; char c=getchar();
  18. while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
  19. while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
  20. return ans*f;
  21. }
  22. int n, m, q;
  23. int head[N], size;
  24. struct edge{int to, next, val;}e[N*3];
  25. inline void add(int s, int t, int w) {e[++size].to=t; e[size].val=w; e[size].next=head[s]; head[s]=size;}
  26. namespace force{
  27. bool none[N];
  28. int dfs(int u, int to, int fa, int now, int sum) {
  29. //cout<<"dfs "<<u<<' '<<to<<' '<<fa<<' '<<now<<' '<<sum<<endl;
  30. if (u==to) return sum;
  31. int ans=0;
  32. for (int i=head[u],v; ~i; i=e[i].next) {
  33. v = e[i].to;
  34. if (v==fa || none[v]) continue;
  35. ans=max(ans, dfs(v, to, u, e[i].val, sum+(now!=e[i].val)));
  36. }
  37. if (!ans) none[u]=1;
  38. return ans;
  39. }
  40. void solve() {
  41. for (int i=1,u,v,w; i<=m; ++i) {
  42. u=read(); v=read(); w=read();
  43. add(u, v, w); add(v, u, w);
  44. }
  45. q=read();
  46. if (!q) exit(0);
  47. for (int i=1,x,y; i<=q; ++i) {
  48. x=read(); y=read();
  49. memset(none, 0, sizeof(bool)*(n+5));
  50. printf("%d\n", dfs(x, y, 0, 0, 0));
  51. }
  52. exit(0);
  53. }
  54. }
  55. namespace task1{
  56. bool none[N];
  57. int dfs(int u, int to, int fa, int now, int sum, int dis) {
  58. //cout<<"dfs "<<u<<' '<<to<<' '<<fa<<' '<<now<<' '<<sum<<endl;
  59. if (dis>60) {none[u]=1; return 0;}
  60. if (u==to) return sum;
  61. int ans=0;
  62. for (int i=head[u],v; ~i; i=e[i].next) {
  63. v = e[i].to;
  64. if (v==fa || none[v]) continue;
  65. ans=max(ans, dfs(v, to, u, e[i].val, sum+(now!=e[i].val), dis+1));
  66. }
  67. if (!ans) none[u]=1;
  68. return ans;
  69. }
  70. void solve() {
  71. for (int i=1,u,v,w; i<=m; ++i) {
  72. u=read(); v=read(); w=read();
  73. add(u, v, w); add(v, u, w);
  74. }
  75. q=read();
  76. if (!q) exit(0);
  77. for (int i=1,x,y; i<=q; ++i) {
  78. x=read(); y=read();
  79. memset(none, 0, sizeof(bool)*(n+5));
  80. printf("%d\n", dfs(x, y, 0, 0, 0, 0));
  81. }
  82. exit(0);
  83. }
  84. }
  85. namespace task{
  86. int fa[N][25], dep[N], lg[N], rot, siz[N], msiz[N], sumsiz;
  87. bool rm[N];
  88. struct st{int i, j, k; st() {} st(int a, int b, int c):i(a),j(b),k(c){}};
  89. inline bool operator == (st a, st b) {return a.i==b.i&&a.j==b.j&&a.k==b.k;}
  90. inline bool operator < (st a, st b) {return a.k<b.k;}
  91. struct pair_hash{inline size_t operator () (pair<int, int> p) const {return hash<int>()(p.fir*p.sec+p.fir);}};
  92. unordered_map<pair<int, int>, vector<int>*, pair_hash> mp{5000, pair_hash()};
  93. unordered_map<pair<int, int>, vector<st>*, pair_hash> dp{20000, pair_hash()};
  94. unordered_map<pair<int, int>, int, pair_hash> tem{50, pair_hash()};
  95. struct edge{int to, next;}e2[N<<1];
  96. inline void add(int s, int t) {e2[++size].to=t; e2[size].next=head[s]; head[s]=size;}
  97. vector<int> e[N];
  98. void getrt(int u, int fa) {
  99. //cout<<"getrt"<<u<<' '<<fa<<endl;
  100. siz[u]=1; msiz[u]=0;
  101. for (register auto v:e[u]) {
  102. if (!rm[v] && v!=fa) {
  103. getrt(v, u);
  104. siz[u]+=siz[v];
  105. msiz[u]=max(msiz[u], siz[v]);
  106. }
  107. }
  108. //cout<<"sumsiz: "<<sumsiz<<' '<<sumsiz-siz[u]<<' '<<msiz[u]<<' '<<msiz[rot]<<' '<<rot<<endl;
  109. msiz[u]=max(msiz[u], sumsiz-siz[u]);
  110. if (msiz[u]<msiz[rot]) rot=u;
  111. }
  112. void info(int u, int fa) {
  113. //cout<<"info "<<u<<' '<<fa<<endl;
  114. for (register auto v:e[u]) {
  115. if (v==fa || rm[v]) continue;
  116. if (rot==u) {
  117. if (dp.find(make(u, v))==dp.end()) dp[make(u, v)]=new vector<st>;
  118. auto t1=mp[make(u, v)]; auto t2=dp[make(u, v)];
  119. for (register auto it:*t1)
  120. t2->pb(st(it, it, 1));
  121. }
  122. else {
  123. if (dp.find(make(rot, v))==dp.end()) dp[make(rot, v)]=new vector<st>;
  124. for (register auto it:*dp[make(rot, u)])
  125. for (register auto t:*mp[make(u, v)])
  126. tem[make(it.i, t)] = max(tem[make(it.i, t)], it.k+(it.j!=t));
  127. register auto t1=dp[make(rot, v)];
  128. for (register auto it:tem) t1->pb(st(it.fir.fir, it.fir.sec, it.sec));
  129. //assert(tem.size()<=9);
  130. tem.clear();
  131. }
  132. info(v, u);
  133. //cout<<"size: "<<dp.size()<<endl;
  134. }
  135. }
  136. void build(int u) {
  137. //cout<<"build "<<u<<endl;
  138. rm[u]=1;
  139. info(u, 0);
  140. for (register auto v:e[u]) {
  141. rot=0;
  142. if (!rm[v]) {
  143. sumsiz=siz[v];
  144. getrt(v, u);
  145. add(u, rot), add(rot, u);
  146. //info(rot, u, t);
  147. build(rot);
  148. }
  149. }
  150. }
  151. void dfs(int u, int pa) {
  152. //cout<<"dfs "<<u<<' '<<pa<<endl;
  153. for (reg i=1; i<25; ++i)
  154. if (dep[u]>=(1<<i)) fa[u][i] = fa[fa[u][i-1]][i-1];
  155. else break;
  156. for (reg i=head[u],v; ~i; i=e2[i].next) {
  157. v = e2[i].to;
  158. if (v!=pa) dep[v]=dep[u]+1, fa[v][0]=u, dfs(v, u);
  159. }
  160. }
  161. int lca(int a, int b) {
  162. if (dep[a]<dep[b]) swap(a, b);
  163. while (dep[a]>dep[b]) a=fa[a][lg[dep[a]-dep[b]]-1];
  164. if (a==b) return a;
  165. for (reg i=lg[dep[a]]-1; ~i; --i)
  166. if (fa[a][i]!=fa[b][i])
  167. a=fa[a][i], b=fa[b][i];
  168. return fa[a][0];
  169. }
  170. void solve() {
  171. for (reg i=1; i<=n; ++i) lg[i]=lg[i-1]+(1<<lg[i-1]==i);
  172. pair<int, int> t1, t2;
  173. for (reg i=1,u,v,w; i<=m; ++i) {
  174. u=read(); v=read(); w=read();
  175. e[u].pb(v); e[v].pb(u);
  176. t1=make(u, v), t2=make(v, u);
  177. if (mp.find(t1)==mp.end()) mp[t1]=new vector<int>;
  178. mp[t1]->pb(w);
  179. if (mp.find(t2)==mp.end()) mp[t2]=new vector<int>;
  180. mp[t2]->pb(w);
  181. }
  182. for (reg i=1,siz; i<=n; ++i) {
  183. sort(e[i].begin(), e[i].end());
  184. siz=unique(e[i].begin(), e[i].end())-e[i].begin();
  185. e[i].resize(siz);
  186. }
  187. for (register auto it:mp) {
  188. sort(it.sec->begin(), it.sec->end());
  189. int siz=unique(it.sec->begin(), it.sec->end())-it.sec->begin();
  190. it.sec->resize(min2(siz, 3));
  191. }
  192. msiz[0]=sumsiz=n;
  193. getrt(1, 0);
  194. int root=rot;
  195. //cout<<"root: "<<root<<endl;
  196. build(rot);
  197. dep[root]=1;
  198. dfs(root, 0);
  199. //for (auto it:dp) cout<<it.fir.i<<' '<<it.fir.j<<' '<<it.fir.k<<' '<<it.fir.h<<' '<<it.sec<<endl;
  200. q=read(); if (!q) exit(0);
  201. for (reg i=1,x,y,t,ans; i<=q; ++i) {
  202. x=read(); y=read();
  203. if (x==y) {puts("0"); continue;}
  204. t=lca(x, y); ans=0;
  205. //cout<<"lca: "<<x<<' '<<y<<' '<<t<<endl;
  206. if (t==x || t==y) {
  207. //puts("pos1");
  208. if (t!=x) swap(x, y);
  209. for (register auto it:*dp[make(t, y)]) ans=max(ans, it.k);
  210. printf("%d\n", ans);
  211. continue;
  212. }
  213. for (register auto i:*dp[make(t, x)])
  214. for (register auto j:*dp[make(t, y)])
  215. ans = max(ans, i.k+j.k-(i.i==j.i));
  216. printf("%d\n", ans);
  217. }
  218. //cout<<"size: "<<dp.size()<<endl;
  219. exit(0);
  220. }
  221. }
  222. signed main()
  223. {
  224. memset(head, -1, sizeof(head));
  225. n=read(); m=read();
  226. //if (n<100000) force::solve();
  227. //else task1::solve();
  228. task::solve();
  229. return 0;
  230. }

题解 c(留坑)的更多相关文章

  1. Codeforces Round #364 (Div. 1)(vp) 没什么题解就留坑待填

    我就做了前两题,第一题第一次vp就把我搞自闭跑路了,第二题第二次又把我搞自闭了 A. As Fast As Possible 细节题 #include<cstdio> #include&l ...

  2. [kuangbin带你飞]专题十一 网络流个人题解(L题留坑)

    A - ACM Computer Factory 题目描述:某个工厂可以利用P个部件做一台电脑,有N个加工用的机器,但是每一个机器需要特定的部分才能加工,给你P与N,然后是N行描述机器的最大同时加工数 ...

  3. 题解 queen(留坑)

    传送门 博客园突然打不开了,奇奇怪怪的-- 少写个等号没看出来 nm写反了没看出来 考完5min全拍出来了 手残属性加持 不对拍等于爆零 yysy,我连卢卡斯定理的存在都忘了-- 发现要让一大堆皇后能 ...

  4. 2.18比赛(T2,T3留坑)

    2.18比赛(T2,T3留坑) pdf版题面 pdf版题解 超越一切(ak) [题目描述] 夏洛可得到一个(h+1)×(w+1)的巧克力,这意味着她横着最多可 以切 h 刀,竖着最多可以切 w 刀 她 ...

  5. CPU虚拟化技术(留坑)

    留坑~~~ 不知道这个是这么实现的 CPU虚拟化技术就是单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率.虚 ...

  6. 【留坑】uva12299

    这么sb的题本来想练练手记过就是过不了 拍半天也没问题 留坑 哪天有空了去linux下面试试 #include<cstdio> #include<cstring> #inclu ...

  7. 【问题解决方案】Git bash进入多层子目录问题(通配符问题留坑)

    cd进入指定路径下:cd 斜杠 斜杠 方法一: 1- 撇丿,不是"那",盘符前面要加上 / (d盘前面也加,不加也行) 2- 路径名不区分大小写 3- 不用空格 4- 如果目录名中 ...

  8. 题解 Six(留坑)

    传送门 考场上搞了个三进制状压,结果正确性假了-- 有想到从约数下手,但觉得就光预处理约数复杂度就爆炸就没往这边想-- 首先是关于约数个数的证明,再一次感谢战神: 因为 \(n = \prod p_i ...

  9. 培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)

    补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...

随机推荐

  1. C# 8.0和.NET Core 3.0高级编程 分享笔记二:编程基础第二部分

    这一篇是接上一篇笔记的第二部分. 2.5深入研究控制台应用程序 前面创建并使用了基本的控制台应用程序,下面更深入地研究它们. 控制台应用程序是基于文本的,在命令上运行的.它们通常执行需要编写脚本的简单 ...

  2. abp知识

    领域驱动开发的特点:1.分层更多,前期代码量大,后期维护方便2.业务进行了专业的领域划分,业务逻辑更加清晰,便于业务扩展.3.代码工程高内聚,更加精简.4.主要是解决复杂业务逻辑编写问题 为什么要使用 ...

  3. phpstudy后门复现遇到的坑

    这几天遇到一个phpstudy后门的站之前没复现过,结果遇到了深坑记录一下 首先用这个脚本去验证是没问题的: https://github.com/NS-Sp4ce/PHPStudy_BackDoor ...

  4. 华为交换机5855设置ssh

    配置思路 配置交换机密钥对 #生成RSA密钥对 设置vty登陆用户界面的认证方式为AAA认证 #设置远程认证方式 设置aaa用户信息 #本地用户名和密码 #本地用户服务类型 #本地用户授权等级 设置s ...

  5. MySQL数据库性能优化该如何入手

    今天小杨给大家分享一篇关于数据库查询优化,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情. ...

  6. python 常用命令sys.exit()

    Python的程序有两中退出方式:os._exit(), sys.exit() os._exit()会直接将python程序终止,之后的所有代码都不会继续执行. sys.exit()会引发一个异常:S ...

  7. iframe跨域访问出现的cookie问题,提供两种解决方案

    最近在java项目对接时出现的一个问题.A系统嵌入B系统页面时,使用iframe去嵌入B系统页面丢失sessionid,导致B系统认为是未进行登录的请求,从而跳转到了B系统登录页. 解决方法查看此博客 ...

  8. JavaScript实现拖放效果

    JavaScript实现拖放效果 笔者实现该效果也是套用别人的轮子的.传送门 然后厚颜无耻的贴别人的readme~,笔者为了方便查阅就直接贴了,有不想移步的可以看这篇.不过还是最好请到原作者的GitH ...

  9. nacos Connection refused (Connection refused)

    记录一次"异常bug",具体信息如下.主要是记录一下处理过程,可能口水话比较多,如果想看结果,直接往后拉即可. 最后一行 起初,运维同事找到我,跟我说程序出问题了,系统升级,一直连 ...

  10. 我去!爬虫遇到JS逆向AES加密反爬,哭了

    今天准备爬取网页时,遇到『JS逆向AES加密』反爬.比如这样的: 在发送请求获取数据时,需要用到参数params和encSecKey,但是这两个参数经过JS逆向AES加密而来. 既然遇到了这个情况,那 ...