传送门

首先考虑N^2做法,每次从一个点出发,如果到达一个点,然后到达这个点的时间\(\le\)离这个点最近的叶子距离\(di_x\),那么答案+1,否则继续找点

这个暴力很不好优化.可以这样认为,如果某个点贡献答案,那么子树里的点也要贡献答案(某个点走不下去,那么走子树内的点也走不下去,也符合条件),不过一个子树一共只贡献1.可以发现一个子树度数和\(\sum deg_i\),加上1为子树大小*2,即\(\sum 2-deg_i=1\),所以单次询问的答案就是所有符合条件的点的\(2-deg_i\)之和

现在考虑每个点对(x,y),y对x的贡献,要满足\(dis_{x,y}\le di_y\).考虑点分治,那么记某个点到分治重心距离为\(dep_x\),那么对x造成贡献的点y要满足\(dep_x+dep_y\le di_y\),即\(dep_x\le di_y-dep_y\),那么这个可以树状数组快速算贡献

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define LL long long
  4. #define uLL unsigned long long
  5. #define il inline
  6. #define re register
  7. using namespace std;
  8. const int N=7e4+10;
  9. il int rd()
  10. {
  11. int 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],dg[N],tot=1;
  17. il void add(int x,int y)
  18. {
  19. ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++dg[x];
  20. ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot,++dg[y];
  21. }
  22. int n,fa[N],dd[N];
  23. void dfs1(int x)
  24. {
  25. dd[x]=dg[x]==1?0:n+1;
  26. for(int i=hd[x];i;i=nt[i])
  27. {
  28. int y=to[i];
  29. if(y!=fa[x])
  30. {
  31. fa[y]=x,dfs1(y);
  32. if(dd[x]>dd[y]+1) dd[x]=dd[y]+1;
  33. }
  34. }
  35. }
  36. void dfs2(int x)
  37. {
  38. for(int i=hd[x];i;i=nt[i])
  39. {
  40. int y=to[i];
  41. if(y!=fa[x])
  42. {
  43. if(dd[y]>dd[x]+1) dd[y]=dd[x]+1;
  44. dfs2(y);
  45. }
  46. }
  47. }
  48. int c[N<<1];
  49. il void ad(int x,int y){while(x<=n+n) c[x]+=y,x+=x&(-x);}
  50. il int gsm(int x){int an=0;while(x) an+=c[x],x-=x&(-x);return an;}
  51. bool ban[N];
  52. int sz[N],size,rt,rsz,st[N][2],tp,an[N];
  53. void grt(int x,int ffa)
  54. {
  55. sz[x]=1;
  56. int ma=0;
  57. for(int i=hd[x];i;i=nt[i])
  58. {
  59. int y=to[i];
  60. if(y!=ffa&&!ban[y])
  61. {
  62. grt(y,x),sz[x]+=sz[y];
  63. ma=max(ma,sz[y]);
  64. }
  65. }
  66. ma=max(ma,size-sz[x]);
  67. if(ma<rsz) rsz=ma,rt=x;
  68. }
  69. void dfs3(int x,int ffa,int de)
  70. {
  71. st[++tp][0]=de,st[tp][1]=x;
  72. for(int i=hd[x];i;i=nt[i])
  73. {
  74. int y=to[i];
  75. if(y!=ffa&&!ban[y]) dfs3(y,x,de+1);
  76. }
  77. }
  78. void cal(int x,int ffa,int op)
  79. {
  80. tp=0,dfs3(x,ffa,ffa>0);
  81. for(int i=1;i<=tp;++i) ad(dd[st[i][1]]-st[i][0]+n,2-dg[st[i][1]]);
  82. for(int i=1;i<=tp;++i) an[st[i][1]]+=op*gsm(st[i][0]+n);
  83. for(int i=1;i<=tp;++i) ad(dd[st[i][1]]-st[i][0]+n,-(2-dg[st[i][1]]));
  84. }
  85. void sov(int x)
  86. {
  87. rt=0,rsz=size,grt(x,0);
  88. x=rt;
  89. cal(x,0,1),ban[x]=1;
  90. for(int i=hd[x];i;i=nt[i])
  91. if(!ban[to[i]])
  92. {
  93. int y=to[i];
  94. cal(y,x,-1);
  95. size=sz[y],sov(y);
  96. }
  97. }
  98. int main()
  99. {
  100. n=rd();
  101. for(int i=1;i<n;++i) add(rd(),rd());
  102. dfs1(1),dfs2(1);
  103. size=n,sov(1);
  104. for(int i=1;i<=n;++i) printf("%d\n",dd[i]?an[i]:1);
  105. return 0;
  106. }

luogu P4183 [USACO18JAN]Cow at Large P的更多相关文章

  1. [洛谷P4183][USACO18JAN]Cow at Large P

    题目链接 Bzoj崩了之后在洛谷偶然找到的点分好题! 在暴力的角度来说,如果我们$O(n)$枚举根节点,有没有办法在$O(n)$的时间内找到答案呢? 此时如果用树形$dp$的想法,发现是可做的,因为可 ...

  2. 洛谷 P4183 - [USACO18JAN]Cow at Large P(点分治)

    洛谷题面传送门 点分治 hot tea. 首先考虑什么样的点能够对以 \(u\) 为根的答案产生 \(1\) 的贡献.我们考虑以 \(u\) 为根对整棵树进行一遍 DFS.那么对于一个点 \(v\), ...

  3. [USACO18JAN]Cow at Large G(树形DP)

    P4186 [USACO18JAN]Cow at Large G(树形DP) Luogu4186 设dp[i]表示i点需要放多少个农民.则有 \(if(near[i]-dep[i]<=dep[i ...

  4. [USACO18JAN]Cow at Large P

    Description: 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有 \(N\) 个结点的树,结点分别编号为 \(1,2,\ldots, N\) .每个叶子结点都是出入口.开始时,每个出入口都 ...

  5. P4186 【[USACO18JAN]Cow at Large G】

    思路是覆盖子树,我们发现,农民想截住牛的最优策略是不断向上来尽可能地覆盖更大的子树 我们想要尽早地覆盖一个子树,一个显然的贪心是在这个子树中选取深度最小的一个放农民 如果我们在一个点放置了农民,那么其 ...

  6. [USACO18JAN] Cow at Large G (dfs)

    题目大意:有一只狐狸从给定的S点开始逃跑(出发),向叶节点移动以逃离这棵树,叶节点可能出现农民去抓捕狐狸,当农民和狐狸出现在同一个节点的时候,狐狸会被抓住,农民和狐狸移动速度相同,求抓捕狐狸所需要的最 ...

  7. luogu P1821 Silver Cow Party

    题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the b ...

  8. luogu P4183 Cow at Large P (暴力吊打点分治)(内有时间复杂度证明)

    题面 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有N个结点的树,结点分别编号为 1,2,-,N .每个叶子结点都是出入口.开始时,每个出入口都可以放一个农民(也可以不放).每个时刻,贝茜和农民都 ...

  9. [LUOGU] P3611 [USACO17JAN]Cow Dance Show奶牛舞蹈

    https://www.luogu.org/problemnew/show/P3611 二分答案+优先队列 二分O(logn) 判一次正确性O(nlogn) 总体O(nlognlogn) 为了让pri ...

随机推荐

  1. iView 的分页结合表格用法

    HTML: <Table border stripe ref="selection" :columns="columns" :data="now ...

  2. [luogu3388][割点]

    题目链接 思路 真板子题.割点是指在一个无向图中,删去之后图将不再连通的点.可以用tarjan算法求.根据割点有两种情况,一种是根,一种是非根.如果不是根的就去判断在tarjan的时候当前节点所能到的 ...

  3. java 中,new一个新对象时,是先给成员变量赋上初值后 再来调用类中的构造函数的。

    今天学习时法现一个问题,我们定义了一个Test类,在主类中new了一个他的对象,发现:在新建对象中所有的成员变量是先给定了默认初值的:0,null或者false, 之后再调用的构造函数.(如果变量是由 ...

  4. TestNg 5.类分组

    类分组是可以给类去分组,几个类分成不同的组. 比如,建立3个类GroupsOnClass1,GroupsOnClass2,GroupsOnClass3.   GroupsOnClass1和Groups ...

  5. C++基础知识--DAY2

    昨天我们主要是讲的C++相对于C语言的变化,结尾讲述了一点引用的基础知识,要明白,引用就是对一个变量取别名,在C++中需要用指针的都可以思考是否可以用引用来代替. 1. 常引用 常引用(const s ...

  6. 0基础如何学Android开发

    链接:http://pan.baidu.com/s/1bIEIse 密码:ky7w https://pan.baidu.com/s/1i53bs6x提取码:0pwthttps://www.zhihu. ...

  7. Vuex速学篇:(2)利用state保存新闻数据

    回顾 以前我们在做这个新闻列表的时候,是一个写死的数据 export default{ data(){ return{ newslist:[ {newsid:"101",pubti ...

  8. 对manacher的一点感性理解

    因为总是忘掉板子所以这里贴一下我个人对\(manacher\)的感性理解. 可能不够严谨求轻喷\(QwQ\) char ch = getchar (); s[0] = s[1] = '#'; whil ...

  9. qml: 另类图像轮播;

    一般来说,图像轮播都是采用ListView等model进行设计, 比较方便.  这里展示我自己设计的图像轮播 方案, 仅采用两个QImage实现: 下面展示代码以及简述:(注:  以下代码为本人原创, ...

  10. 三台机器之间ssh互信配置

    三台机器之间ssh互信配置 环境介绍:192.168.65.128    my1-222192.168.65.129  my2-223192.168.65.130    web224 # 步骤一:# ...