30%:暴力

40%:枚举L,R从L~n枚举,R每增大一个,更新需要的边(bfs实现)60%:枚举每条边,

计算每条边的贡献另外20%的数据:枚举每条边,计算每条边的贡献100%:对于每一条边统计

有多少个区间跨过这条边即可统计这一问题的对偶问题,有多少个区间没跨过会更方便使用启发式合并+

并查集统计子树内的,使用启发式合并+set统计子树外的

代码:

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<set>
  4. #include<vector>
  5. #include<iostream>
  6. #define LL long long
  7. #define int long long
  8. using namespace std;
  9. const int MAXN = 1e5 + 10;
  10. inline int read() {
  11. char c = getchar(); int x = 0, f = 1;
  12. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  13. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  14. return x * f;
  15. }
  16. int N, siz[MAXN], son[MAXN], dsu[MAXN], Son, vis[MAXN], ds[MAXN];
  17. vector<int> v[MAXN];
  18. set<int> s;
  19. LL outt, inn, ans;
  20. void dfs(int x, int _fa)
  21. {
  22. siz[x] = 1;
  23. for(int i = 0; i < v[x].size(); i++) {
  24. int to = v[x][i]; if(to == _fa) continue;
  25. dfs(to, x);
  26. siz[x] += siz[to];
  27. if(siz[to] > siz[son[x]]) son[x] = to;
  28. }
  29. }
  30. LL calc(LL x) {
  31. return x * (x - 1) / 2;
  32. }
  33. void Clear() {
  34. s.clear();
  35. outt = calc(N);
  36. inn = 0;
  37. s.insert(0);
  38. s.insert(N + 1);
  39. }
  40. int find(int x)
  41. {
  42. return dsu[x] == x ? dsu[x] : dsu[x] = find(dsu[x]);
  43. }
  44. void solve(int x)
  45. {
  46. s.insert(x);
  47. set<int>::iterator s1, s2, it;
  48. s1 = s2 = it = s.find(x);
  49. s1--; s2++;
  50. outt -= calc((*s2) - (*s1) - 1);
  51. outt += calc((*s2) - (*it) - 1) + calc((*it) - (*s1) - 1);
  52. vis[x] = 1;
  53. if(vis[x - 1]) {
  54. int fx = find(x - 1), fy = find(x);
  55. inn += ds[fx] * ds[fy];
  56. dsu[fx] = fy;
  57. ds[fy] += ds[fx];
  58. }
  59. if(vis[x + 1]) {
  60. int fx = find(x + 1), fy = find(x);
  61. inn += ds[fx] * ds[fy];
  62. dsu[fx] = fy;
  63. ds[fy] += ds[fx];
  64. }
  65. }
  66. void Add(int x, int fa)
  67. {
  68. solve(x);
  69. for(int i = 0; i < v[x].size(); i++)
  70. {
  71. int to = v[x][i];
  72. if(to == fa || to == Son) continue;
  73. Add(to, x);
  74. }
  75. }
  76. void Delet(int x, int fa) {
  77. vis[x] = 0; ds[x] = 1; dsu[x] = x;
  78. for(int i = 0; i < v[x].size(); i++) {
  79. int to = v[x][i];
  80. if(to == fa) continue;
  81. Delet(to, x);
  82. }
  83. }
  84. void dfs2(int x, int fa, int opt)
  85. {
  86. for(int i = 0; i < v[x].size(); i++)
  87. {
  88. int to = v[x][i];
  89. if(to == fa || (to == son[x])) continue;
  90. dfs2(to, x, 0);
  91. }
  92. if(son[x]) dfs2(son[x], x, 1); Son = son[x];
  93. Add(x, fa);
  94. ans += calc(N) - inn - outt;
  95. if(opt == 0) Delet(x, fa), Clear(), Son = 0;
  96. }
  97. signed main()
  98. {
  99. #ifdef yilnr
  100. #else
  101. freopen("treecnt.in","r",stdin);
  102. freopen("treecnt.out","w",stdout);
  103. #endif
  104. N = read();
  105. for(int i = 1; i <= N - 1; i++)
  106. {
  107. int x = read(), y = read();
  108. v[x].push_back(y);
  109. v[y].push_back(x);
  110. }
  111. for(int i = 1; i <= N; i++) dsu[i] = i,ds[i] = 1;
  112. dfs(1,0);
  113. Clear();
  114. dfs2(1,0,0);
  115. printf("%lld\n",ans);
  116. return 0;
  117. }
  118. /*
  119. 4
  120. 1 4
  121. 1 3
  122. 2 4
  123. */

【csp模拟赛6】树上统计-启发式合并,线段树合并的更多相关文章

  1. 【CSP模拟赛】God knows (李超线段树)

    题面 CODE 稍微分析一下,发现把(i,pi)(i,p_i)(i,pi​)看做二维数点,就是求极长上升子序列的权值最小值. 直接李超线段树 #include <bits/stdc++.h> ...

  2. 5.20 省选模拟赛 T1 图 启发式合并 线段树合并 染色计数问题

    LINK:图 在说这道题之前吐槽一下今天的日子 520 = 1+1+4+514. /cy 这道题今天做的非常失败 一点分都没拿到手 关键是今天的T3 把我整个人给搞崩了. 先考虑 如果得到了这么一张图 ...

  3. HDU - 4358 Boring counting (树上启发式合并/线段树合并)

    题目链接 题意:统计树上每个结点中恰好出现了k次的颜色数. dsu on tree/线段树合并裸题. 启发式合并1:(748ms) #include<bits/stdc++.h> usin ...

  4. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

  5. 启发式合并 splay合并 线段树合并基础

    Gold is everywhen! - somebody 启发式合并 将小的集合一个个插入到大的集合. 每次新集合大小至少比小集合大一倍,因此每个元素最多合并\(\log n\)次,总复杂度为\(n ...

  6. 启发式合并&线段树合并/分裂&treap合并&splay合并

    启发式合并 有\(n\)个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素. ​ 我们可以用平衡树/set维护集合. ​ 对于合并两个\(A,B\),如果\(|A|<|B|\),那么 ...

  7. [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并

    好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...

  8. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

  9. [NOIP10.6模拟赛]2.equation题解--DFS序+线段树

    题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...

  10. 【CSP模拟赛】避难向导(倍增lca&树的直径)

    耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...

随机推荐

  1. ActiveMQ Queue示例

    一.Queue 发送 public class JmsSend { public static void main(String[] args) throws JMSException { Conne ...

  2. Django 中 app_name (应用命名空间) 和 namespace (实例命名空间) 的区别

    转自:https://www.jianshu.com/p/404500a0408a 补充理解: 先把官网上对应用命名空间(app_name)和实例命名空间(namespace)的解释贴上: app_n ...

  3. (六)lucene之其他查询方式(组合查询,制定数字范围、指定字符串开头)

    本章使用的是lucene5.3.0 指定数字范围查询 package com.shyroke.test; import java.io.IOException; import java.nio.fil ...

  4. 【转载】在使用JDBC连接MySql时报错:You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support

    在使用JDBC连接MySql时报错:You must configure either the server or JDBC driver (via the serverTimezone config ...

  5. .netcore项目中使用log4net

    log4net配置文件 引入log4net包,创建一个config目录,专门用来放配置文件,添加log4net.config文件. 编写配置文件. <?xml version="1.0 ...

  6. JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用

    jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default   Lambda表达式     L ...

  7. windows下监控进程的脚本

    相信大家都有这样的需求,某程序(进程)在运行的时候可能挂掉,需要去监控该程序,并在它挂掉的时候重启之,确保该程序能一直运行.比如土net就经常挂,需要监控程序去监控.Linux下面似乎有守护进程的概念 ...

  8. 使用HTML CSS制作简易三角形和旗帜

    HTML:     <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. c#排序sql语句查询

    排序存储的效果图: 根据id排序的sql存储过程: DECLARE @type varchar() ' ' Order By charindex(','+ convert(varchar,id) +' ...

  10. openpose-opencv 的body数据多人体姿态估计

    介绍 opencv除了支持常用的物体检测模型和分类模型之外,还支持openpose模型,同样是线下训练和线上调用.这里不做特别多的介绍,先把源代码和数据放出来- 实验模型获取地址:https://gi ...