luogu P4183 [USACO18JAN]Cow at Large P
首先考虑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\),那么这个可以树状数组快速算贡献
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define il inline
#define re register
using namespace std;
const int N=7e4+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],dg[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++dg[x];
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot,++dg[y];
}
int n,fa[N],dd[N];
void dfs1(int x)
{
dd[x]=dg[x]==1?0:n+1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=fa[x])
{
fa[y]=x,dfs1(y);
if(dd[x]>dd[y]+1) dd[x]=dd[y]+1;
}
}
}
void dfs2(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=fa[x])
{
if(dd[y]>dd[x]+1) dd[y]=dd[x]+1;
dfs2(y);
}
}
}
int c[N<<1];
il void ad(int x,int y){while(x<=n+n) c[x]+=y,x+=x&(-x);}
il int gsm(int x){int an=0;while(x) an+=c[x],x-=x&(-x);return an;}
bool ban[N];
int sz[N],size,rt,rsz,st[N][2],tp,an[N];
void grt(int x,int ffa)
{
sz[x]=1;
int ma=0;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=ffa&&!ban[y])
{
grt(y,x),sz[x]+=sz[y];
ma=max(ma,sz[y]);
}
}
ma=max(ma,size-sz[x]);
if(ma<rsz) rsz=ma,rt=x;
}
void dfs3(int x,int ffa,int de)
{
st[++tp][0]=de,st[tp][1]=x;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=ffa&&!ban[y]) dfs3(y,x,de+1);
}
}
void cal(int x,int ffa,int op)
{
tp=0,dfs3(x,ffa,ffa>0);
for(int i=1;i<=tp;++i) ad(dd[st[i][1]]-st[i][0]+n,2-dg[st[i][1]]);
for(int i=1;i<=tp;++i) an[st[i][1]]+=op*gsm(st[i][0]+n);
for(int i=1;i<=tp;++i) ad(dd[st[i][1]]-st[i][0]+n,-(2-dg[st[i][1]]));
}
void sov(int x)
{
rt=0,rsz=size,grt(x,0);
x=rt;
cal(x,0,1),ban[x]=1;
for(int i=hd[x];i;i=nt[i])
if(!ban[to[i]])
{
int y=to[i];
cal(y,x,-1);
size=sz[y],sov(y);
}
}
int main()
{
n=rd();
for(int i=1;i<n;++i) add(rd(),rd());
dfs1(1),dfs2(1);
size=n,sov(1);
for(int i=1;i<=n;++i) printf("%d\n",dd[i]?an[i]:1);
return 0;
}
luogu P4183 [USACO18JAN]Cow at Large P的更多相关文章
- [洛谷P4183][USACO18JAN]Cow at Large P
题目链接 Bzoj崩了之后在洛谷偶然找到的点分好题! 在暴力的角度来说,如果我们$O(n)$枚举根节点,有没有办法在$O(n)$的时间内找到答案呢? 此时如果用树形$dp$的想法,发现是可做的,因为可 ...
- 洛谷 P4183 - [USACO18JAN]Cow at Large P(点分治)
洛谷题面传送门 点分治 hot tea. 首先考虑什么样的点能够对以 \(u\) 为根的答案产生 \(1\) 的贡献.我们考虑以 \(u\) 为根对整棵树进行一遍 DFS.那么对于一个点 \(v\), ...
- [USACO18JAN]Cow at Large G(树形DP)
P4186 [USACO18JAN]Cow at Large G(树形DP) Luogu4186 设dp[i]表示i点需要放多少个农民.则有 \(if(near[i]-dep[i]<=dep[i ...
- [USACO18JAN]Cow at Large P
Description: 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有 \(N\) 个结点的树,结点分别编号为 \(1,2,\ldots, N\) .每个叶子结点都是出入口.开始时,每个出入口都 ...
- P4186 【[USACO18JAN]Cow at Large G】
思路是覆盖子树,我们发现,农民想截住牛的最优策略是不断向上来尽可能地覆盖更大的子树 我们想要尽早地覆盖一个子树,一个显然的贪心是在这个子树中选取深度最小的一个放农民 如果我们在一个点放置了农民,那么其 ...
- [USACO18JAN] Cow at Large G (dfs)
题目大意:有一只狐狸从给定的S点开始逃跑(出发),向叶节点移动以逃离这棵树,叶节点可能出现农民去抓捕狐狸,当农民和狐狸出现在同一个节点的时候,狐狸会被抓住,农民和狐狸移动速度相同,求抓捕狐狸所需要的最 ...
- 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 ...
- luogu P4183 Cow at Large P (暴力吊打点分治)(内有时间复杂度证明)
题面 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有N个结点的树,结点分别编号为 1,2,-,N .每个叶子结点都是出入口.开始时,每个出入口都可以放一个农民(也可以不放).每个时刻,贝茜和农民都 ...
- [LUOGU] P3611 [USACO17JAN]Cow Dance Show奶牛舞蹈
https://www.luogu.org/problemnew/show/P3611 二分答案+优先队列 二分O(logn) 判一次正确性O(nlogn) 总体O(nlognlogn) 为了让pri ...
随机推荐
- java 数组声明定义 数组内存分配 数组初始化 数组引用 数组的遍历
一,数组的定义 Java 中定义数组的语法有两种: 1. type arrayName[]; 2. type[] arrayName;type 为Java中的任意数据类型,包括基本类型和组合类型,ar ...
- CF1101
D:题意:树上每个顶点有个权值,求最长链,满足链上gcd > 1 解:对每个质数建虚树,每个点只会拆成log个点,所以是log2的. #include <bits/stdc++.h> ...
- textarea高度自适应自动展开
在使用之前,推荐两个比较好的事件,分别是oninput和onpropertychange,IE9以下不兼容oninput.在textarea发生变化时,可以通过监听这两个事件来触发你需要的功能. te ...
- 2. github创建 git仓库,克隆,拉取和推送操作(所有的git命令前提是一定在当前项目目录下)
步骤: 1.点击小猫,回到初始页面 2.点击start a project,首先会出现一个验证email地址(我们注册的时候,有一个email输入,进去邮箱验证一下) 3.重新点击start a pr ...
- template specifiers not specified in declaration of ‘template<class Key> class hash’
尝试写显示特化样例的时候,写了如下代码 #include <iostream> #include <cstddef> using namespace std; #define ...
- JS with
<script type="text/javascript"> function Dog(){ this.type="dog"; this.tail ...
- python 学习笔记:python例子
廖雪峰python网站 #if els # -*- coding: utf-8 -*- #list是一种有序的集合,可以随时添加和删除其中的元素. ''' classmates=['a','b','c ...
- CentOS7利用systemctl添加自定义系统服务
CentOS7的每一个服务以.service结尾,一般会分为3部分:[Unit].[Service]和[Install] 转载于互联网 [Unit] 部分主要是对这个服务的说明,内容包括Descrip ...
- window下域名解析系统DNS诊断命令nslookup详解
Ping指令我们很熟悉了,它是一个检查网络状况的命令,在输入的参数是域名的情况下会通过DNS进行查询,但只能查询A记录和CNAME(别名)记录,还会返回域名是否存在,其他的信息都是没有的.如果你需要对 ...
- opencv源码学习: getGaussianKernel( 高斯核);
参考: https://blog.csdn.net/u012633319/article/details/80921023 二维高斯核, 可以根据下面的公式推到为两个一维高斯核的乘积: 原型: /** ...