2017国家集训队作业[agc008f]Black Radius

时隔4个月,经历了省赛打酱油和中考各种被吊打后,我终于回想起了我博客园的密码= =

题意:

​ 给你一棵树,树上有若干个关键点。选中某个关键点和一个参数d,把所有与关键点距离不超过距离d的点染黑,问一共有多少种染色方案,两种染色方案不同当且仅当存在一个节点在两种方案中的颜色不同,初始全为白色。(点数\(N\leq2*10^5\))

题解:

​ 好题啊,模拟赛遇到这题真的orz不会做:)

​ 做这种题,套路就是找到一种不重不漏的计数方式。假设所有点都是关键点,考虑用二元组\((u,d)\)来表示与\(u\)距离不超过\(d\)的集合,那么,我们要求的其实是所有本质不同的\((u,d)\)的个数。

​ \(\bullet\)考虑本质不同的\((u,d)\)有什么性质

​ \(\bullet1.\)要钦定\((u,d)\)不能是全集,最后\(ans\)再加上一就行了

​ \(\bullet2.\)对于所有相邻的点\(u\)和\(v\),\((u,d)\)不能与\((v,d-1)\)相同

​ 我们记\(u\)与最远点的距离为\(mxd(u)\),\(u\)与次远点的距离为\(sxd(u)\),则这两点就等价于:

\[\begin{cases}
d< mxd(u) \\
d<sxd(u)+2
\end{cases}
\]

证明:

​ 一式显然。

​ 不妨设\(u\)是\(v\)的父亲,当前\(d\)使得\(u\)在以它为起点的最长链上点集包括的最远点为\(k\),我们考虑如何让\((u,d)\)与\(v\)的某个二元组出现重复。

​ 有两种情况:

​ \(\bullet v\)在以它为起点的最长链上,此时为了保证让\((v,d')\)在这条链上的最远点依然为\(k\),则有\(d'=d-1\)。但这时,\((v,d')\)在\(u\)的其它儿子的子树中的最远点向上移了2位,为了保证它们是相同的,就有\(d\ge sxd(u)+2\)。

​ \(\bullet v\)不在最长链上,同上则\(d'=d+1\),此时一定会满足\(d+1\ge sxd(v)+2\)。

​ 反之即\(d<sxd(u)+2\),证毕。

​ 于是我们就可以愉快地拿到全部是关键点的部分分。

​ 现在我们考虑当它不全是关键点的情况。

​ 对于一个非关键点\(u\),和关键点\(v\),为了满足\((u,d)\)是\(v\)的染色的方案,\((u,d)\)必须包涵\(v\)子树内的所有点,这是\(d\)的下界。对于关键点\(u\)它的\(d\)的下界为\(0\)。树型DP处理即可,时间复杂度\(O(N)\)。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
inline int rd()
{
static int x,f;
x=0,f=1;
char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
const int N=200010,Inf=1000000000;
struct edge{
int v,next;
edge(int v=0,int next=0):v(v),next(next){}
}e[N<<1];
int n;ll ans=0;
int head[N],tot=0;
int mx[N],sx[N],mn[N],siz[N];
char s[N]; inline void add(int u,int v){e[++tot]=edge(v,head[u]);head[u]=tot;} void dfs1(int u,int fat)
{
if(s[u]=='1')mn[u]=0,siz[u]=1;
else mn[u]=Inf;
fe(i,u){
int v=e[i].v;
if(v==fat)continue;
dfs1(v,u);siz[u]+=siz[v];
int dis=mx[v]+1;
if(mx[u]<dis)sx[u]=mx[u],mx[u]=dis;
else sx[u]=max(sx[u],dis);
if(siz[v])mn[u]=min(mn[u],dis);
}
}
void dfs2(int u,int fat)
{
int mxd=min(mx[u]-1,sx[u]+1);
if(mxd>=mn[u])ans+=(ll)mxd-mn[u]+1;
fe(i,u){
int v=e[i].v;
if(v==fat)continue;
int dis=mx[u]==mx[v]+1?sx[u]+1:mx[u]+1;
if(mx[v]<dis)sx[v]=mx[v],mx[v]=dis;
else sx[v]=max(sx[v],dis);
if(siz[v]<siz[1])mn[v]=min(mn[v],dis);
dfs2(v,u);
}
} int main()
{
n=rd();
fo(i,1,n-1){
int x=rd(),y=rd();
add(x,y);add(y,x);
}
scanf("%s",s+1);
dfs1(1,0);dfs2(1,0);
printf("%lld\n",ans+1ll);
return 0;
}

2017国家集训队作业[agc008f]Black Radius的更多相关文章

  1. 2017国家集训队作业Atcoder题目试做

    2017国家集训队作业Atcoder题目试做 虽然远没有达到这个水平,但是据说Atcoder思维难度大,代码难度小,适合我这种不会打字的选手,所以试着做一做 不知道能做几题啊 在完全自己做出来的题前面 ...

  2. 2017国家集训队作业[agc016b]Color Hats

    2017国家集训队作业[agc016b]Color Hats 题意: 有\(N\)个人,每个人有一顶帽子.帽子有不同的颜色.现在,每个人都告诉你,他看到的所有其它人的帽子共有多少种颜色,问有没有符合所 ...

  3. 2017国家集训队作业[agc016e]Poor Turkey

    2017国家集训队作业[agc016e]Poor Turkey 题意: 一开始有\(N\)只鸡是活着的,有\(M\)个时刻,每个时刻有两个数\(X_i,Y_i\),表示在第\(i\)个时刻在\(X_i ...

  4. 2017国家集训队作业[agc006f]Blackout

    2017国家集训队作业[agc006f]Blackout 题意: 有一个\(N*N\)的网格,一开始有\(M\)个格子被涂黑,给出这\(M\)个格子,和染色操作:如果有坐标为\((x,y),(y,z) ...

  5. 2017国家集训队作业[agc004f]Namori

    2017国家集训队作业[agc004f]Namori 题意: 给你一颗树或环套树,树上有\(N\)个点,有\(M\)条边.一开始,树上的点都是白色,一次操作可以选择一条端点颜色相同的边,使它的端点颜色 ...

  6. 2017国家集训队作业[arc082d]Sandglass

    2017国家集训队作业[arc082d]Sandglass 题意: ​ 有一个沙漏,初始时\(A\)瓶在上方,两个瓶子的最大容量都为\(X\)克,沙子流动的速度为\(1g\)每单位时间.给出\(K\) ...

  7. 2017国家集训队作业[arc076d/f][Exhausted?]

    2017国家集训队作业[arc076d/f][Exhausted?] 题意: ​ 有\(N\)个人,\(M\)把椅子,给出\(...L_i.R_i\)表示第\(i\)个人可以选择编号为\(1\sim ...

  8. 2017国家集训队作业[agc006e]Rotate 3x3

    2017国家集训队作业[agc006e]Rotate 3x3 题意: ​ 给你一个\(3*N\)的网格,每次操作选择一个\(3*3\)的网格,旋转\(180^\circ\).问可不可以使每个位置\(( ...

  9. 2017国家集训队作业[agc014d]Black and White Tree

    2017国家集训队作业[agc014d]Black and White Tree 题意: ​ 有一颗n个点的树,刚开始每个点都没有颜色.Alice和Bob会轮流对这棵树的一个点涂色,Alice涂白,B ...

随机推荐

  1. ipad mini2 升级9.0.2后解锁白屏解决

    解锁白屏是个什么现象?就是当你用手指滑动解锁后出现输入密码的界面后,1秒之内屏幕变白,中间一个黑色的苹果,几秒之后重新回到滑动解锁的界面.我出现这个现象不是因为升级了9.0.2,而是升级了9.0.2之 ...

  2. 在Ubuntu上创建一个可以启动的U盘

    1.概观 使用可启动的Ubuntu USB盘,您可以: 安装或升级Ubuntu 在不触及PC配置的情况下测试Ubuntu桌面体验 在借来的机器或网吧上启动到Ubuntu 使用USB盘上默认安装的工具来 ...

  3. SCO Openserver、SCO Unix、SCO UnixWare、Solaris几者到底是什么关系,有什么相同或不同?

    Unix操作系统的历史漫长而曲折,它的第一个版本是1969年由Ken Thompson在AT&T贝尔实验室实现的,运行在一台DEC PDP-7计算机上.这个系统非常粗糙,与现代Unix相差很远 ...

  4. 使用WinNTSetup安装win10时提示efi part有红叉(win10安装UEFI系统安装)

    1.装载ImDisk虚拟磁盘 2.格式化硬盘 *格式化时注意”创建新ESP分区 3.使用 WinNTSetup 选择win10安装程序 *1. “BOOTMGR PBR "后有感叹号不用管, ...

  5. es6 学习2 模板字符

    es6模板字符简直是开发者的福音啊,解决了ES5在字符串功能上的痛点. 1.第一个用途,基本的字符串格式化.将表达式嵌入字符串中进行拼接.用${}来界定 //es5 var name = 'lux' ...

  6. Java Web MVC 一个实例的手动实现

    平台: tomcat7.0    Servlet3.0    Windows命令行编译 实现的功能: 在网页上可以进行对Product类的三个属性的输入,点击保存之后跳转到另一个显示输入内容的界面 文 ...

  7. Python对象的循环引用问题

    目录 Python对象循环引用 循环引用垃圾回收算法 容器对象 生成容器对象 追踪容器对象 结束追踪容器对象 分代容器对象链表 何时执行循环引用垃圾回收 循环引用的垃圾回收 循环引用中的终结器 pyt ...

  8. #ifdef__cplusplus

    百度知道: 一般用于将C++代码以标准C形式输出(即以C的形式被调用),这是因为C++虽然常被认为是C的超集,但是C++的编译器还是与C的编译器不同的.C中调用C++中的代码这样定义会是安全的. 一般 ...

  9. swift 笔记 (十一) —— 方法(类,结构体,枚举)

    Methods (方法) 实例方法(Instance Methods) 我认为看到这里.我们唯能八一八的就是swift的自做主张的行为了,反正它就是会以各种方式帮助我们来完毕让代码看起来非常奇怪的事情 ...

  10. 优化数据页面(20)——1:n的数据关系

    设计要点:优化数据页面.界面设计.美化exce 阿金:那一对多的关系-- 秀秀:不是:n结构么? 阿金:嗯,这俺知道.俺特别喜欢这样的格式,那样显得非常上档次! 秀秀:俺也喜欢. 由于页面上有空白,认 ...