线段树合并的话这个noip最难题就是个裸题了。

  注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<vector>
  8. using namespace std;
  9. int read()
  10. {
  11. int x=,f=;char c=getchar();
  12. while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
  13. while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
  14. return x*f;
  15. }
  16. #define N 300010
  17. int n,m,p[N],a[N],fa[N][],deep[N],ans[N],root[][N],cnt[]={},t=;
  18. vector<int> op1[N],op2[N];
  19. struct data{int to,nxt;
  20. }edge[N<<];
  21. struct data2{int l,r,x;
  22. }tree[][N<<];
  23. void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
  24. void dfs(int k)
  25. {
  26. for (int i=p[k];i;i=edge[i].nxt)
  27. if (edge[i].to!=fa[k][])
  28. {
  29. fa[edge[i].to][]=k;
  30. deep[edge[i].to]=deep[k]+;
  31. dfs(edge[i].to);
  32. }
  33. }
  34. int lca(int x,int y)
  35. {
  36. if (deep[x]<deep[y]) swap(x,y);
  37. for (int j=;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
  38. if (x==y) return x;
  39. for (int j=;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
  40. return fa[x][];
  41. }
  42. int merge(int x,int y,int l,int r,int p)
  43. {
  44. if (!x||!y) return x|y;
  45. if (l==r) {tree[p][x].x+=tree[p][y].x;return x;}
  46. int mid=l+r>>;
  47. tree[p][x].l=merge(tree[p][x].l,tree[p][y].l,l,mid,p);
  48. tree[p][x].r=merge(tree[p][x].r,tree[p][y].r,mid+,r,p);
  49. return x;
  50. }
  51. void ins(int &k,int x,int l,int r,int v,int p)
  52. {
  53. if (!k) k=++cnt[p];
  54. if (l==r) {tree[p][k].x+=v;return;}
  55. int mid=l+r>>;
  56. if (x<=mid) ins(tree[p][k].l,x,l,mid,v,p);
  57. else ins(tree[p][k].r,x,mid+,r,v,p);
  58. }
  59. int query(int k,int l,int r,int x,int p)
  60. {
  61. if (!k) return ;
  62. if (l==r) return tree[p][k].x;
  63. int mid=l+r>>;
  64. if (x<=mid) return query(tree[p][k].l,l,mid,x,p);
  65. else return query(tree[p][k].r,mid+,r,x,p);
  66. }
  67. void getans(int k)
  68. {
  69. for (int i=p[k];i;i=edge[i].nxt)
  70. if (edge[i].to!=fa[k][])
  71. {
  72. getans(edge[i].to);
  73. root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
  74. root[][k]=merge(root[][k],root[][edge[i].to],,n<<,);
  75. }
  76. for (int i=;i<op1[k].size();i++)
  77. if (op1[k][i]>) ins(root[][k],op1[k][i],,n<<,,);
  78. else ins(root[][k],-op1[k][i],,n<<,-,);
  79. for (int i=;i<op2[k].size();i++)
  80. if (op2[k][i]>) ins(root[][k],op2[k][i],,n<<,,);
  81. else ins(root[][k],-op2[k][i],,n<<,-,);
  82. ans[k]+=query(root[][k],,n<<,deep[k]+a[k],)+query(root[][k],,n<<,deep[k]-a[k]+n,);
  83. }
  84. int main()
  85. {
  86. #ifndef ONLINE_JUDGE
  87. freopen("bzoj4719.in","r",stdin);
  88. freopen("bzoj4719.out","w",stdout);
  89. #endif
  90. n=read(),m=read();
  91. for (int i=;i<n;i++)
  92. {
  93. int x=read(),y=read();
  94. addedge(x,y),addedge(y,x);
  95. }
  96. fa[][]=;dfs();
  97. for (int j=;j<;j++)
  98. for (int i=;i<=n;i++)
  99. fa[i][j]=fa[fa[i][j-]][j-];
  100. for (int i=;i<=n;i++) a[i]=read();
  101. for (int i=;i<=m;i++)
  102. {
  103. int x=read(),y=read(),l=lca(x,y);
  104. if (l!=x) op1[x].push_back(deep[x]),op1[l==?:fa[l][]].push_back(-deep[x]);
  105. if (l!=y) op2[y].push_back(deep[l]*-deep[x]+n),op2[l==x?(l==?:fa[l][]):l].push_back(deep[x]-deep[l]*-n);
  106. if (l==x&&l==y&&a[l]==) ans[l]++;
  107. }
  108. getans();
  109. for (int i=;i<=n;i++) printf("%d ",ans[i]);
  110. return ;
  111. }

BZOJ4719 NOIP2016天天爱跑步(线段树合并)的更多相关文章

  1. [NOIp2016]天天爱跑步 线段树合并

    [NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...

  2. NOIP2016 天天爱跑步 线段树合并_桶_思维题

    竟然独自想出来了,好开心 Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r&q ...

  3. 2018.08.09 bzoj4719: [Noip2016]天天爱跑步(树链剖分)

    传送门 话说开始上文化课之后写题时间好少啊. 这道题将一个人的跑步路线拆成s->lca,lca->t,然后对于第一段上坡路径要经过的点,当前这个人能对它产生贡献当且仅当dep[s]-dep ...

  4. BZOJ4719 [Noip2016]天天爱跑步

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  5. 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并

    题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...

  6. LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)

    题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...

  7. [NOIP2016 DAY1 T2]天天爱跑步-[差分+线段树合并][解题报告]

    [NOIP2016 DAY1 T2]天天爱跑步 题面: B[NOIP2016 DAY1]天天爱跑步 时间限制 : - MS 空间限制 : 565536 KB 评测说明 : 2s Description ...

  8. [NOIP2016]天天爱跑步(树上差分+线段树合并)

    将每个人跑步的路径拆分成x->lca,lca->y两条路径分别考虑: 对于在点i的观察点,这个人(s->t)能被观察到的充要条件为: 1.直向上的路径:w[i]=dep[s]-dep ...

  9. 洛谷P1600 天天爱跑步(线段树合并)

    小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...

随机推荐

  1. tkinter菜单图标,工具栏

    所用的图片: import tkinter as tk from tkinter import messagebox, filedialog, simpledialog, colorchooser f ...

  2. 【LG3973】[TJOI2015]线性代数

    [LG3973][TJOI2015]线性代数 题面 洛谷 题解 正常解法 一大堆矩阵乘在一起很丑对吧 化一下柿子: \[ D=(A*B-C)*A^T\\ \Leftrightarrow D=\sum_ ...

  3. 【BZOJ4803】逆欧拉函数

    [BZOJ4803]逆欧拉函数 题面 bzoj 题解 题目是给定你\(\varphi(n)\)要求前\(k\)小的\(n\). 设\(n=\prod_{i=1}^k{p_i}^{c_i}\) 则\(\ ...

  4. 利用 Intel Realsense做SLAM开发(一)

    最近手里拿到一台Realsense D435,就是这个: https://click.intel.com/intelr-realsensetm-depth-camera-d435.html 所以准备拿 ...

  5. C++自学第一课:函数

    此贴并非教学,主要是自学笔记,所述内容只是些许个人学习心得的记录和备查积累,难以保证观点正确,也不一定能坚持完成. 如不幸到访,可能耽误您的时间,也难及时回复,贴主先此致歉.如偶有所得,相逢有缘,幸甚 ...

  6. json_encode替代函数

    <?php   function jsonEncode($var) {     if (function_exists('json_encode')) {         return json ...

  7. Zookeeper--java操作zookeeper

    如果是使用java操作zookeeper,zookeeper的javaclient 使我们更轻松的去对zookeeper进行各种操作,我们引入zookeeper-3.4.5.jar 和 zkclien ...

  8. 高可用Kubernetes集群-4. kubectl客户端工具

    六.部署kubectl客户端工具 1. 下载 [root@kubenode1 ~]# cd /usr/local/src/ [root@kubenode1 src]# wget https://sto ...

  9. RHCE6.0上午的考试一键完成

    #!/sbin/bash # #initial envirment #variable define IPADDR=192.168.0.12 NETMASK=255.255.255.0 HOSTNAM ...

  10. linux 的 awk 使用

    linux中awk命令对文本内容进行操作,其功能十分强大 1.如:查看一个有几百万行内容的文件中第3列数字内容(不重复) cat test.csv | awk -F ',' '{print $3}' ...