树上差分

这应该是一道很简单的树上差分了。。就是问每个点被覆盖了多少次。

要注意我们最后dfs后,要把除第一个节点以外的所有点的-1,因为有些点作为起点和终点覆盖了两次,按照题目意思是不用覆盖两次的。

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. #define full(a, b) memset(a, b, sizeof a)
  4. using namespace std;
  5. typedef long long ll;
  6. inline int lowbit(int x){ return x & (-x); }
  7. inline int read(){
  8. int X = 0, w = 0; char ch = 0;
  9. while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
  10. while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  11. return w ? -X : X;
  12. }
  13. inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
  14. inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
  15. template<typename T>
  16. inline T max(T x, T y, T z){ return max(max(x, y), z); }
  17. template<typename T>
  18. inline T min(T x, T y, T z){ return min(min(x, y), z); }
  19. template<typename A, typename B, typename C>
  20. inline A fpow(A x, B p, C lyd){
  21. A ans = 1;
  22. for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
  23. return ans;
  24. }
  25. const int N = 300005;
  26. int n, s[N], cnt, head[N], depth[N], p[N][20], t, val[N];
  27. bool vis[N];
  28. struct Edge { int v, next; }edge[N<<1];
  29. void addEdge(int a, int b){
  30. edge[cnt].v = b, edge[cnt].next = head[a], head[a] = cnt ++;
  31. }
  32. void dfs(int s, int fa){
  33. depth[s] = depth[fa] + 1;
  34. p[s][0] = fa;
  35. for(int i = 1; i <= t; i ++){
  36. p[s][i] = p[p[s][i - 1]][i - 1];
  37. }
  38. for(int i = head[s]; i != -1; i = edge[i].next){
  39. int u = edge[i].v;
  40. if(u == fa) continue;
  41. dfs(u, s);
  42. }
  43. }
  44. int lca(int x, int y){
  45. if(depth[x] < depth[y]) swap(x, y);
  46. for(int i = t; i >= 0; i --){
  47. if(depth[p[x][i]] >= depth[y]) x = p[x][i];
  48. }
  49. if(x == y) return y;
  50. for(int i = t; i >= 0; i --){
  51. if(p[x][i] != p[y][i]) x = p[x][i], y = p[y][i];
  52. }
  53. return p[y][0];
  54. }
  55. void dfs(int s){
  56. vis[s] = true;
  57. for(int i = head[s]; i != -1; i = edge[i].next){
  58. int u = edge[i].v;
  59. if(vis[u]) continue;
  60. dfs(u);
  61. val[s] += val[u];
  62. }
  63. }
  64. int main(){
  65. full(head, -1);
  66. n = read();
  67. for(int i = 0; i < n; i ++) s[i] = read();
  68. for(int i = 0; i < n - 1; i ++){
  69. int u = read(), v = read();
  70. addEdge(u, v), addEdge(v, u);
  71. }
  72. t = (int)(log(n) / log(2)) + 1;
  73. dfs(s[0], 0);
  74. for(int i = 0; i < n - 1; i ++){
  75. val[s[i]] ++, val[s[i + 1]] ++;
  76. int f = lca(s[i], s[i + 1]);
  77. val[f] --, val[p[f][0]] --;
  78. }
  79. dfs(s[0]);
  80. for(int i = 1; i < n; i ++) val[s[i]] --;
  81. for(int i = 1; i <= n; i ++) printf("%d\n", val[i]);
  82. return 0;
  83. }

洛谷P3258 松鼠的新家的更多相关文章

  1. 洛谷 P3258 松鼠的新家 题解

    题面 貌似这道题暴力加玄学优化就可以AC? 下面是正解: 1.树链剖分: 我们在u到v之间都放一个糖果,可以将松鼠它家u到v的糖果数都加1.每一次将a[i]到a[i+1] (a数组是访问顺序)的节点加 ...

  2. 洛谷 [P3258] 松鼠的新家

    树上差分 对于一条路径 \(u->v\) 来说,设 \(t=LCA(u,v)\) ,d[]为差分数组 ,则有 d[u]++;d[v]++;d[t]--;d[fa[t]]--; 注意:题目中所给的 ...

  3. 洛谷P3258松鼠的新家

    题目传送门 恩,很明显的一个树剖题,配合树上差分其实也并不难,不过无奈蒟蒻树剖还没那么熟练,而且树上差分也做的少,所以这题愣是做了一中午......唉,果然我还是太菜了.恩,具体做法在代码中解释吧: ...

  4. P3258 松鼠的新家

    松鼠的新家 洛谷链接 尽管标签是省选/NOI-,但提交的通过率已经高到三分之一了. 但它仍旧是一个省选/NOI-的题. 大致题意就是按输入的顺序走一棵树,看每个节点经过多少次.问题就相当于把一条链上的 ...

  5. 【题解】P3258松鼠的新家

    [题解][P3258 JLOI2014]松鼠的新家 树链剖分板子题. 总结一点容易写错的地方吧: if(d[top[u]]<d[top[v]]) swap(u,v);注意是\(top\). 在\ ...

  6. Luogu P3258 松鼠的新家(树链剖分+线段树/树状数组)

    题面 题解 这种题目一看就是重链剖分裸题,还是区间修改,单点查询,查询之前在遍历时要记一个\(delta\),因为这一次的起点就是上一次的终点,不需要放糖,所以可以用\(BIT\)来写,但我写完\(m ...

  7. BZOJ3631:[JLOI2014]松鼠的新家——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3631 https://www.luogu.org/problemnew/show/P3258 松鼠的 ...

  8. 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...

  9. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

随机推荐

  1. CentOS 6 升级 curl

    zabbix 发邮件报 Support for SMTP authentication was not compiled in 其实出现这种问题的原因是我们机器上的 libcurl 版本太低所致.在z ...

  2. H5 62-浮动元素字围现象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Generalized Power Method for Sparse Principal Component Analysis

    目录 重点 算法 这篇文章,看的晕晕的,但是被引用了400多次了,就简单地记一笔. 这个东西,因为\(\ell_1\)范数,所以会稀疏化,当然,和\(\gamma\)有关. 重点 我想重点写的地方是下 ...

  4. import导入模块,==和is,浅拷贝和深拷贝,进制转换,位运算,私有化,property装饰器

    '''import导入模块'''import sysprint(sys.path) sys.path.append('D://ASoft/Python/PycharmProjects')import ...

  5. T-shirt buying CodeForces - 799B (小根堆+STL)

    题目链接 思路: 由于题目说了只有1,2,3,三种色号的衣服,然后开三个对应色号的小根堆, 我是根据pair<int,int> 创建了一个以价格小的优先的优先队列. pair中的另外一个i ...

  6. 实分析p78 两个解释

    1. 是为了存在一个充分大的J,使得,当j大于J.会满足.x是满足能一致收敛到f(x)自变量取得集合,, 是为了允许有限个 前面的不成立,是对所有的k都成立,让k取很大,可以很小 2.是函数列收敛到f ...

  7. MySQL中关于数据类型指定宽度之后的情况

    概述 MySQL有很多种数据类型,最常用的就是int,char,varchar,这些类型在创建表的时候都可以指定该字段的宽度,方法是在类型后面加一个括号,括号中写宽度就可以了. 但是,在指定宽度之后, ...

  8. Python3练习题 011:成绩打分

    # print('-----判断输入值和60大小判断')# b=int(input('input num'))# if b >60:# print('良')# elif b==60:# prin ...

  9. SQL server 生成数据字典

    Set nocount on ), ) DECLARE Tbls CURSOR FOR ),isnull(g.[value],'-')) AS TABLE_COMMENT FROM INFORMATI ...

  10. laravel打印sql

    DB::connection()->enableQueryLog(); print_r(DB::getQueryLog());