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. POJ 1320 Street Numbers(佩尔方程)

    Street Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3078   Accepted: 1725 De ...

  2. iOS——集成支付宝 private key is NULL

    问题描述:将生成的私钥,写进官方demo,还是一直报错:rsa_private read error : private key is NULL 解决方案:需要将RSA私钥转换成PKCS8格式

  3. d3 bubble源码分析

    技术 d3.d3.pack.d3.hierarchy 展示 https://bl.ocks.org/xunhanliu/e0688dc2ae9167c4c7fc264c0aedcdd1 关于怎么使用, ...

  4. 洛谷3388 【模板】割点 tarjan算法

    题目描述 给出一个n个点,m条边的无向图,求图的割点. 关于割点 在无向连通图中,如果将其中一个点以及所有连接该点的边去掉,图就不再连通,那么这个点就叫做割点(cut vertex / articul ...

  5. NOIP2016 天天爱跑步(树上差分)

    题意 给定一棵树,从时刻 0 开始,有若干人从 S[i] 出发向 T[i] 移动,每单位时刻移动一条边 对于树上每个点 x,求 w[x]  时刻有多少人恰好路过 x N,M≤300000 题解 从上午 ...

  6. ATP自造8Gb内存颗粒供DDR3使用

    随着整个行业已经全面转向DDR4内存,不少厂商都陆续停产了DDR3,并准备好了迎接DDR5,但对于很多特殊用户,尤其是网络和嵌入式领域,仍然对DDR3有着强劲且持续的需求. 工业内存存储厂商ATP E ...

  7. ln---创建链接

    ln命令用来为文件创件连接,连接类型分为硬连接和符号连接两种,默认的连接类型是硬连接.如果要创建符号连接必须使用"-s"选项. 注意:符号链接文件不是一个独立的文件,它的许多属性依 ...

  8. C语言typedef struct具体解释

    在C中定义一个结构体要用typedef,如: typedef struct Student { int a; }Stu; 于是在声明变量的时候就能够:Stu stu1;(假设没有typedef就必须用 ...

  9. 一个美丽的java烟花程序

    <img src="http://img.blog.csdn.net/20150625104525974?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ...

  10. Sqlite 命令行导出、导入数据(直接支持CSV)

    打开命令行 导出数据到data.csv D:\project>sqlite3.exe old.db SQLite version 3.21.0 2017-10-24 18:55:49 Enter ...