传送门

1A此题暴祭

(下面记点\(x\)深度为\(de_x\),某个时间点记为\(w_x\))

首先,每条路径是可以拆成往上和往下两条路径的

对于往上的路径,假设有个人往上跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x+de_x=w_y+de_y\)

对于往下的路径,假设有个人往下跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x-de_x=w_y-de_y\)

所以对于每个点开两个线段树,每个下表存\(w_x+de_x\)或\(w_x-de_x\)的点的个数,对于每条路径(x,y),记\(len\)为路径长度(结束时间点),\(mid\)为到达\(lca\)的时间,在\(x\)的第一个线段树的\(de_x\)处+1,在\(lca\)的第一个线段树的\(mid+de_{lca}\)处-1,在y的第二个线段树的\(len-de_y+n\)处+1,在\(fa_{lca}\)的第二个线段树的\(mid-1-de_{fa_{lca}}+n\)处-1(不能出现负下标).dfs整棵树,把\(x\)所有儿子的线段树并起来,然后这个点的答案就是第一棵线段树的\(w_x+de_x\)加第二棵线段树的\(w_x-de_x+n\)的值

我太傻了,这两颗线段树可以分开处理的,我放在一起处理了,空间爆炸,bzoj就过不去了qwq

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define il inline
  4. #define re register
  5. #define db double
  6. #define eps (1e-5)
  7. using namespace std;
  8. const int N=300000+10;
  9. il LL rd()
  10. {
  11. LL x=0,w=1;char ch=0;
  12. while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  13. while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  14. return x*w;
  15. }
  16. int to[N<<1],nt[N<<1],hd[N],tot=1;
  17. il void add(int x,int y)
  18. {
  19. ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
  20. ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
  21. }
  22. int n,m,w[N],an[N],fa[N],sz[N],de[N],son[N],top[N];
  23. void dfs1(int x)
  24. {
  25. sz[x]=1;
  26. for(int i=hd[x];i;i=nt[i])
  27. {
  28. int y=to[i];
  29. if(y==fa[x]) continue;
  30. fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
  31. if(sz[son[x]]<sz[y]) son[x]=y;
  32. }
  33. }
  34. void dfs2(int x,int ntp)
  35. {
  36. top[x]=ntp;
  37. if(son[x]) dfs2(son[x],ntp);
  38. for(int i=hd[x];i;i=nt[i])
  39. {
  40. int y=to[i];
  41. if(y==fa[x]||y==son[x]) continue;
  42. dfs2(y,y);
  43. }
  44. }
  45. il int glca(int x,int y)
  46. {
  47. while(top[x]!=top[y])
  48. {
  49. if(de[top[x]]<de[top[y]]) swap(x,y);
  50. x=fa[top[x]];
  51. }
  52. return de[x]<de[y]?x:y;
  53. }
  54. struct sgtree
  55. {
  56. int s[(N*3)*20],ch[(N*3)*20][2],rt[N],tt;
  57. sgtree(){tt=0;}
  58. il void inst(int o1,int o2,int x,int dt)
  59. {
  60. int l=1,r=n+n;
  61. s[o1]=s[o2]+dt;
  62. while(l<r)
  63. {
  64. int mid=(l+r)>>1;
  65. if(x<=mid)
  66. {
  67. ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
  68. o1=ch[o1][0],o2=ch[o2][0];
  69. r=mid;
  70. }
  71. else
  72. {
  73. ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
  74. o1=ch[o1][1],o2=ch[o2][1];
  75. l=mid+1;
  76. }
  77. s[o1]=s[o2]+dt;
  78. }
  79. }
  80. int merge(int o1,int o2)
  81. {
  82. if(!o1||!o2) return o1+o2;
  83. int o=++tt;
  84. s[o]=s[o1]+s[o2];
  85. ch[o][0]=merge(ch[o1][0],ch[o2][0]);
  86. ch[o][1]=merge(ch[o1][1],ch[o2][1]);
  87. return o;
  88. }
  89. int quer(int o,int l,int r,int lx)
  90. {
  91. if(!o) return 0;
  92. if(l==r) return s[o];
  93. int mid=(l+r)>>1;
  94. if(lx<=mid) return quer(ch[o][0],l,mid,lx);
  95. else return quer(ch[o][1],mid+1,r,lx);
  96. }
  97. }S,T;
  98. il void dfs3(int x)
  99. {
  100. for(int i=hd[x];i;i=nt[i])
  101. {
  102. int y=to[i];
  103. if(y==fa[x]) continue;
  104. dfs3(y),S.rt[x]=S.merge(S.rt[x],S.rt[y]),T.rt[x]=T.merge(T.rt[x],T.rt[y]);
  105. }
  106. an[x]=S.quer(S.rt[x],1,n+n,w[x]+de[x])+T.quer(T.rt[x],1,n+n,w[x]-de[x]+n);
  107. }
  108. int main()
  109. {
  110. n=rd(),m=rd();
  111. for(int i=1;i<n;i++) add(rd(),rd());
  112. de[1]=1,dfs1(1),dfs2(1,1);
  113. for(int i=1;i<=n;i++) w[i]=rd();
  114. while(m--)
  115. {
  116. int x=rd(),y=rd(),lca=glca(x,y),lth=de[x]+de[y]-(de[lca]<<1),mid=lth-de[y]+de[lca],la;
  117. la=S.rt[x],S.rt[x]=++S.tt,S.inst(S.rt[x],la,de[x],1);
  118. la=S.rt[lca],S.rt[lca]=++S.tt,S.inst(S.rt[lca],la,de[lca]+mid,-1);
  119. la=T.rt[y],T.rt[y]=++T.tt,T.inst(T.rt[y],la,lth-de[y]+n,1);
  120. la=T.rt[fa[lca]],T.rt[fa[lca]]=++T.tt,T.inst(T.rt[fa[lca]],la,mid-1-de[fa[lca]]+n,-1);
  121. }
  122. dfs3(1);
  123. for(int i=1;i<=n;i++) printf("%d ",an[i]);
  124. return 0;
  125. }

luogu P1600 天天爱跑步的更多相关文章

  1. [NOIP 2016D2T2/Luogu P1600] 天天爱跑步 (LCA+差分)

    待填坑 Code //Luogu P1600 天天爱跑步 //Apr,4th,2018 //树上差分+LCA #include<iostream> #include<cstdio&g ...

  2. [luogu]P1600 天天爱跑步[LCA]

    [luogu]P1600 [NOIP 2016]天天爱跑步 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上 ...

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

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

  4. P1600 天天爱跑步[桶+LCA+树上差分]

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

  5. Luogu:P1600 天天爱跑步

    来一发清新的80行 树剖 $LCA$ + 树上差分 题解. -----from Judge 本题题意大概是给出一棵 n 个节点的树以及 m 条有向路径, 并且每个点 i 都有一个权值 $w[i]$,如 ...

  6. 洛谷 P1600 天天爱跑步

    https://www.luogu.org/problemnew/show/P1600 (仅做记录) 自己的假方法: 每一次跑从a到b:设l=lca(a,b)对于以下产生贡献: a到l的链上所有的点( ...

  7. 洛谷P1600 天天爱跑步——树上差分

    题目:https://www.luogu.org/problemnew/show/P1600 看博客:https://blog.csdn.net/clove_unique/article/detail ...

  8. 洛谷P1600 天天爱跑步

    天天放毒... 首先介绍一个树上差分. 每次进入的时候记录贡献,跟出来的时候的差值就是子树贡献. 然后就可以做了. 发现考虑每个人的贡献有困难. 于是考虑每个观察员的答案. 把路径拆成两条,以lca分 ...

  9. P1600 天天爱跑步

    lca真心不太会,这里只介绍60分做法,100的太难辣简单了就不介绍了 n<=1000 zz回溯爆搜 S[i]全部相等 这dfs序都不用lca的,2333,差分,然后输出判断一下是否是0(1到i ...

随机推荐

  1. 14.5 富文本编辑【JavaScript高级程序设计第三版】

    富文本编辑,又称为WYSIWYG(What You See Is What You Get,所见即所得).在网页中编辑富文本内容,是人们对Web 应用程序最大的期待之一.虽然也没有规范,但在IE 最早 ...

  2. unorder_map 自定义KEY

    1. boost::unorder_map 实现自定义KEY // boostLibTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  3. pgm终

    这里罗列一些看完此书后遗留的问题: 常用 model 通过 BP/LBP 重新审视 inference 部分 Lauritzen algorithm/Lauritzen-Spiegelhalter a ...

  4. jenkins--svn+添加钩子去触发jenkins的job工作

    找到svn钩子脚本 post-commit: 添加一个接口: /usr/bin/curl http://admin:admin@x.x.x.x:8080/job/svn/buildWithParame ...

  5. BZOJ4517[Scoi2016]美味——主席树

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为 ...

  6. python3.5opencv3图像文字标注

    import cv2 cv2.namedWindow("mark", cv2.WINDOW_AUTOSIZE) image = cv2.imread("../images ...

  7. MT【12】三点坐标求面积

    $L_1,L_2$是O发出的两条射线,C是一个常数,一条动直线$l$分别与$L_1,L_2$交于A,B两点.$S_{\Delta ABC}=C$,求A,B的中点D的轨迹方程.(2012北大自主招生) ...

  8. 【AGC014E】Blue and Red Tree

    Description 给定一棵\(n\)个节点的蓝边树,再给定一棵\(n\)个节点的红边树.请通过若干次操作将蓝树变成红树.操作要求和过程如下: 1.选定一条边全为蓝色的路径: 2.将路径上的一条蓝 ...

  9. luogu4933 大师 (dp)

    记f[i][j]是以i号为结尾的.公差为j的的个数(不包括只有i的情况) 那么就有$f[i][i-i']=\sum{(f[i'][i-i']+1)}$之类的东西 最后再加个n就行啦 而且公差有可能有负 ...

  10. POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)

    POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Networ ...