luogu P4183 [USACO18JAN]Cow at Large P
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相关推荐
- 【luogu P4183】Cow at Large P(点分治)(图论)(树状数组)
Cow at Large P 题目链接:luogu P4183 题目大意 给你一棵树,然后叶子节点可以放守卫. 然后有个人在树上,然后每个时刻那个人和守卫都可以移动,如果人和守卫相遇人就被抓了,如果人 ...
- [USACO18JAN] Cow at Large G (dfs)
题目大意:有一只狐狸从给定的S点开始逃跑(出发),向叶节点移动以逃离这棵树,叶节点可能出现农民去抓捕狐狸,当农民和狐狸出现在同一个节点的时候,狐狸会被抓住,农民和狐狸移动速度相同,求抓捕狐狸所需要的最 ...
- luogu P4183 Cow at Large P (暴力吊打点分治)(内有时间复杂度证明)
题面 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有N个结点的树,结点分别编号为 1,2,-,N .每个叶子结点都是出入口.开始时,每个出入口都可以放一个农民(也可以不放).每个时刻,贝茜和农民都 ...
- [USACO18JAN][luoguP4183 ]Cow at Large P
前言 这是一道考试题 需要一定的idea 构造好后似乎就是裸的点分治了 题目相关 题目链接 题目大意 这个大意写的很烦,不如看题面 有一棵nnn个点的树 设定一个动点:其每秒可以走到树上相邻的一个节点 ...
- 【JZOJ 省选模拟】鱼池逃脱Cow at Large
题目 Description 胖头鱼从鱼戏团逃脱后,被主人一路追捕,他慌不择路地跑进了一颗n个节点的池子树,池子树的所有度数为1的点就是出口. 假如他现在在节点i,那么每个时刻他能选择向某个与当前点有 ...
- USACO 2018 January Contest
USACO 2018 January Contest 比赛链接 T1 MooTube 题目链接 题目大意:给定一个图,两个点之间的距离是他们路径上边权的最小值.给定一个起点,求距离大于等于K的点有几个 ...
- Nothing spreads like fear——电影《传染病》观后感
Nothing spreads like fear 美国<娱乐周刊>说,这是一部能吓死人的传染病题材惊悚片,看完影片后一定会有想要洗手的强迫症. 但看完之后感觉并没有这么强烈,特别是对于正 ...
- 【差分】Tallest Cow(poj 3263/luogu 2879)
Tallest Cow poj 3263 luogu 2879 题目大意: 现在有n头牛,两头牛如果要相互看到,那他们之间的牛必须比他们两低,现在给出n,最高牛的位置和高度,和m对关系,要你求每头牛最 ...
- 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 [命题人:][下 ...
最新文章
- 一次失败的尝试:paxosstore示例编译
- 基于时间卷积神经网络的概率预测
- android 快速 顶部,Android RecyclerView 快速滑到顶部
- Python之日志处理(logging模块)
- Confluence 6 针对 'unmigrated-wiki-markup' 宏重新尝试合并
- 1.3.3 系统调用(执行过程、访管指令、库函数与系统调用)
- vue组件transition的使用(demo演示) - 教程篇
- QMessagebox简单使用
- 喷水装置2(nyoj12)
- 安装sw时出现sldim停止工作_脉冲滤筒除尘器的安装有哪些小常识
- python画折线图参数配置
- jQuery - 滚动条插件 NiceScroll 使用详解(滚动条美化)
- 基于STM32的AT24C08数据读写
- 科学计算与Matlab笔记:第4章:Matlab绘图
- 木讷的程序员需要知道的事情 (六)
- 计算机系学霸表白,高级暗语表白 学霸隐藏式表白
- 浅谈全概率公式和贝叶斯公式
- int? 是什么类型?和int有何区别
- 利用java swing编写一个简易的计算器,实现了括号,优先级,三角函数,阶乘等功能
- C# 如何捕获键盘按钮和组合键以及KeyPress/KeyDown事件之间的区别 (附KeyChar/KeyCode值)