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. Goldengate进程的合并与拆分规范

    Goldengate抽取进程的合并与拆分原则 1.    文档综述 1.1.  文档说明 本文档描述了对GoldenGate的抽取进程进行拆分和合并的基本原则和详细步骤.  1.2.  读者范围 本文 ...

  2. The IDL compiler

    The IDL compiler or bindings generator transcompiles Web IDL to C++ code, specifically bindings betw ...

  3. tgtadm和iscsiadm命令的用法

    一.tgtadm命令 tgtadm常用于管理三类对象:     target:创建new,删除,查看     lun:创建,查看,删除     account:创建用户,绑定,解绑定,删除,查看 语法 ...

  4. SSD-tensorflow-2 evaluation

    测试就是用voc2007的test set来测试已经训练好的checkpoint的mAP,github上提供了三个已经训练好的model的checkpoint checkpoint 里面已有的300_ ...

  5. java反射与多态(父类调用子类)的代码演示

    package Test0817; import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method ...

  6. mysql优化篇之表分区

             当表的数据量达到一定数量时(如单个.myd文件都达到10G,myd 是mysql的数据文件),这时候读取起来必然效率很低.          1.从业务角度可以解决(分表)      ...

  7. js字符串排序方法

    前端开发过程中有时需自己手写排序方法 一般想到数字的字符串排序方法 我们会用到 var newArr = arr. sort(function(a,b){return a - b})来进行排序 但除此 ...

  8. [NOIP2009提高组]最优贸易

    题目:洛谷P1073.Vijos P1754.codevs1173. 题目大意:有n点m边的图,边分有向和无向.每个点有一个价格,用这个价格可以买入或卖出一个东西.一个人从1出发,要到n,途中可以买入 ...

  9. [WC2011]最大XOR和路径(线性基)

    P4151 [WC2011]最大XOR和路径 题目描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如下( 1 表示真, 0 表 ...

  10. ECNUOJ 2574 Principles of Compiler

    Principles of Compiler Time Limit:1000MS Memory Limit:65536KBTotal Submit:473 Accepted:106 Descripti ...