https://www.luogu.com.cn/problem/P4183

学到许多

显然要求出来一个f[u]f[u]f[u]表示离uuu最近的叶子距离

考虑对于一个节点的情况,把它设为根

求出来以它为根的每个点的深度,记为dep[u]dep[u]dep[u]

手玩一下容易发现对于每个节点,叶子是否需要的放判断是

f[u]<=dep[u],f[fa]>dep[fa]f[u]<=dep[u],f[fa]>dep[fa]f[u]<=dep[u],f[fa]>dep[fa]

那么这个uuu节点(对应的子树)就可以对根产生1的贡献

但是直接这么做非常不好计算,发现难处理的是fafafa

因为产生贡献的一定是子树,所以考虑

对于一棵子树 ∑in[x]=2m−1\sum in[x]=2m-1∑in[x]=2m−1
可以得到1=∑(2−in[x])1=\sum (2-in[x])1=∑(2−in[x])
这要就能保证子树加起来最后的贡献是111

然后考虑计算
那么根据上面那条性质,可以轻易得到

ans=∑[f[u]<=dep[u]](2−in[u])ans=\sum [f[u]<=dep[u]] (2-in[u])ans=∑[f[u]<=dep[u]](2−in[u])
这样就能保证子树的贡献是111

然后我们考虑点分治,以rtrtrt为分治中心

dep[x]+dep[i]>=f[i]dep[x]+dep[i]>=f[i]dep[x]+dep[i]>=f[i]那么iii就能对xxx产生2−in[i]2-in[i]2−in[i]的贡献
用树状数组维护f[i]−dep[i]f[i]-dep[i]f[i]−dep[i]即可

code:


#include<bits/stdc++.h>
#define N 200050
using namespace std;
int f[N], in[N];
vector<int> g[N];
void dfs(int u, int fa) {f[u] = 114514;if(in[u] == 1) f[u] = 0;for(int v : g[u]) {if(v == fa) continue;dfs(v, u);f[u] = min(f[u], f[v] + 1);}
}
void dfss(int u, int fa) {for(int v : g[u]) {if(v == fa) continue;f[v] = min(f[v], f[u] + 1);dfss(v, u);}
}int t[N], n;
#define lowbit(x) (x & -x)
void update(int x, int y) { x += n;for(; x <= 2 * n; x += lowbit(x)) t[x] += y;
}
int query(int x) { x += n;int ret = 0;for(; x; x -= lowbit(x)) ret += t[x];return ret;
}int S, siz[N], vis[N], gs, ls[N], msiz[N], dep[N], ans[N];
void find(int u, int fa) {ls[++ gs] = u;siz[u] = 1; msiz[u] = 0;for(int v : g[u]) {if(v == fa || vis[v]) continue;find(v, u);siz[u] += siz[v];msiz[u] = max(msiz[u], siz[v]);}msiz[u] = max(msiz[u], S - siz[u]);
}
void get(int u, int fa) {ls[++ gs] = u; siz[u] = 1;for(int v : g[u]) {if(v == fa || vis[v]) continue;dep[v] = dep[u] + 1;get(v, u); siz[u] += siz[v];}
}
void calc(int o) {//for(int i = 1; i <= gs; i ++) printf("%d ", ls[i]); printf("\n");for(int i = 1; i <= gs; i ++) {int x = ls[i];update(f[x] - dep[x], 2 - in[x]);//    if(x == 2) printf("%d ", dep[x]);}   for(int i = 1; i <= gs; i ++) {int x = ls[i];ans[x] += o * query(dep[x]);}for(int i = 1; i <= gs; i ++) {int x = ls[i];update(f[x] - dep[x], -(2 - in[x]));}
}
void solve(int u) {gs = 0;find(u, u);for(int i = 1; i <= gs; i ++) if(msiz[ls[i]] < msiz[u]) u = ls[i];//printf("* %d  %d\n", u, siz[u]);gs = 0;dep[u] = 0;get(u, u);calc(1);vis[u] = 1;for(int v : g[u]) {if(vis[v]) continue;gs = 0; get(v, u);calc(-1);S = siz[v];solve(v);}
}
int main() {// freopen("a.in","r",stdin);// freopen("a.out","w",stdout);scanf("%d", &n);for(int i = 1; i < n; i ++) {int u, v;scanf("%d%d", &u, &v);g[u].push_back(v), g[v].push_back(u);in[u] ++, in[v] ++;}dfs(1, 0), dfss(1, 0);S = n; solve(1);for(int i = 1; i <= n; i ++) if(in[i] == 1) ans[i] = 1;for(int i = 1; i <= n; i ++) printf("%d\n", ans[i]);return 0;
}

luogu P4183 [USACO18JAN]Cow at Large P相关推荐

  1. 【luogu P4183】Cow at Large P(点分治)(图论)(树状数组)

    Cow at Large P 题目链接:luogu P4183 题目大意 给你一棵树,然后叶子节点可以放守卫. 然后有个人在树上,然后每个时刻那个人和守卫都可以移动,如果人和守卫相遇人就被抓了,如果人 ...

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

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

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

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

  4. [USACO18JAN][luoguP4183 ]Cow at Large P

    前言 这是一道考试题 需要一定的idea 构造好后似乎就是裸的点分治了 题目相关 题目链接 题目大意 这个大意写的很烦,不如看题面 有一棵nnn个点的树 设定一个动点:其每秒可以走到树上相邻的一个节点 ...

  5. 【JZOJ 省选模拟】鱼池逃脱Cow at Large

    题目 Description 胖头鱼从鱼戏团逃脱后,被主人一路追捕,他慌不择路地跑进了一颗n个节点的池子树,池子树的所有度数为1的点就是出口. 假如他现在在节点i,那么每个时刻他能选择向某个与当前点有 ...

  6. USACO 2018 January Contest

    USACO 2018 January Contest 比赛链接 T1 MooTube 题目链接 题目大意:给定一个图,两个点之间的距离是他们路径上边权的最小值.给定一个起点,求距离大于等于K的点有几个 ...

  7. Nothing spreads like fear——电影《传染病》观后感

    Nothing spreads like fear 美国<娱乐周刊>说,这是一部能吓死人的传染病题材惊悚片,看完影片后一定会有想要洗手的强迫症. 但看完之后感觉并没有这么强烈,特别是对于正 ...

  8. 【差分】Tallest Cow(poj 3263/luogu 2879)

    Tallest Cow poj 3263 luogu 2879 题目大意: 现在有n头牛,两头牛如果要相互看到,那他们之间的牛必须比他们两低,现在给出n,最高牛的位置和高度,和m对关系,要你求每头牛最 ...

  9. 2190: 【USACO】Farmer John has no Large Brown Cow

    2190: [USACO]Farmer John has no Large Brown Cow 时间限制: 1.000 Sec  内存限制: 64 MB 提交: 16  解决: 12 [命题人:][下 ...

最新文章

  1. 一次失败的尝试:paxosstore示例编译
  2. 基于时间卷积神经网络的概率预测
  3. android 快速 顶部,Android RecyclerView 快速滑到顶部
  4. Python之日志处理(logging模块)
  5. Confluence 6 针对 'unmigrated-wiki-markup' 宏重新尝试合并
  6. 1.3.3 系统调用(执行过程、访管指令、库函数与系统调用)
  7. vue组件transition的使用(demo演示) - 教程篇
  8. QMessagebox简单使用
  9. 喷水装置2(nyoj12)
  10. 安装sw时出现sldim停止工作_脉冲滤筒除尘器的安装有哪些小常识
  11. python画折线图参数配置
  12. jQuery - 滚动条插件 NiceScroll 使用详解(滚动条美化)
  13. 基于STM32的AT24C08数据读写
  14. 科学计算与Matlab笔记:第4章:Matlab绘图
  15. 木讷的程序员需要知道的事情 (六)
  16. 计算机系学霸表白,高级暗语表白 学霸隐藏式表白
  17. 浅谈全概率公式和贝叶斯公式
  18. int? 是什么类型?和int有何区别
  19. 利用java swing编写一个简易的计算器,实现了括号,优先级,三角函数,阶乘等功能
  20. C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown事件之间的区别 (附KeyChar/KeyCode值)

热门文章

  1. typescript浅拷贝与深拷贝
  2. 【爬虫】Airtest + 逍遥模拟器 开发 APP爬虫
  3. 常用Oracle Database Server 文件位置
  4. 沸腾20年的互联网,趋于平静,新型开发生态,如日中天
  5. 精致的像素级别的风格转换 ----- Deep Image Analogy
  6. 现在学校应用较多的计算机学籍管理系统,计算机题库(填空题)
  7. Altium Designer18 初步使用参考
  8. ITU-R BT.1886
  9. c语言报告程序分析报告,C语言程序设计报告
  10. 线性高斯反问题--广义逆