解题:CF1118F2 Tree Cutting (Hard Version)
好题不问Div(这是Div3最后一题,不得不说Mike真是强=。=)
首先同一个颜色的点的LCA要和它们在一个划分出的块里,那么我们先按颜色把所有点到它们的LCA的路径涂色,如果这个过程中出现了重合的颜色则说明无解。
之后问题转化为一个树形DP问题,设$dp[i][0/1]$表示以$i$为根的子树中i是否划入一个有颜色的块的方案数。然后讨论转移:
1.如果i自身没有颜色
①如果i不划入有颜色的块,那么直接继承子树信息,乘法原理统计,$dp[i][0]=\prod_{v∈son_i}(dp[v][0]+dp[v][1])$
②如果i划入有颜色的块,那么对于每一个子树都单独统计一遍划入其中的方案数,$dp[i][1]=\sum_{v∈son_i}dp[v][1]\prod_{w∈son_i\&\&w!=v}(dp[w][0]+dp[w][1])$,维护每个节点子节点的前缀后缀乘积来转移
2.如果i自身有颜色
①如果i不划入有颜色的块,那么......不划入有颜色的块=。=???$dp[i][0]=0$
②如果i划入有颜色的块,同理于1.①
(因为一个睿智错误多调了一个小时
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define vint vector<int>
#define vit vector<int>::iterator
using namespace std;
const int N=,mod=;
int p[N],noww[*N],goal[*N],siz[N];
int anc[N],dep[N],imp[N],top[N],col[N],dp[N][];
int n,k,cnt,t1,t2; vint ve[N];
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
noww[++cnt]=p[t];
goal[cnt]=f,p[t]=cnt;
}
void Add(int &x,int y)
{
x+=y;
if(x>=mod) x-=mod;
}
void Mul(int &x,int y)
{
x=1ll*x*y%mod;
}
void DFS(int nde,int fth,int dth)
{
int tmp=;
siz[nde]=,anc[nde]=fth,dep[nde]=dth;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde,dth+);
siz[nde]+=siz[goal[i]];
if(siz[goal[i]]>tmp)
tmp=siz[goal[i]],imp[nde]=goal[i];
}
}
void Decompose(int nde,int tpp)
{
top[nde]=tpp;
if(imp[nde])
{
Decompose(imp[nde],tpp);
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=anc[nde]&&goal[i]!=imp[nde])
Decompose(goal[i],goal[i]);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y); x=anc[top[x]];
}
return dep[x]<dep[y]?x:y;
}
void Climb(int nde,int lca,int cor)
{
while(nde!=lca)
{
nde=anc[nde];
if(col[nde])
{
if(col[nde]==cor) return;
else printf(""),exit();
}
col[nde]=cor;
}
}
void Getans(int nde,int fth)
{
vint v1,v2;
dp[nde][(bool)col[nde]]=;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
int g=goal[i]; Getans(g,nde);
int s=(dp[g][]+dp[g][])%mod;
v1.push_back(s),v2.push_back(s);
col[nde]?Mul(dp[nde][],s):Mul(dp[nde][],s);
}
if(!col[nde]&&v1.size())
{
int sz=v1.size(),pt=;
for(int i=;i<sz;i++) Mul(v1[i],v1[i-]);
for(int i=sz-;i>=;i--) Mul(v2[i],v2[i+]);
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
int pre=pt?v1[pt-]:,suf=(pt==sz-)?:v2[pt+];
int tmp=dp[goal[i]][];
Mul(tmp,pre),Mul(tmp,suf),Add(dp[nde][],tmp),pt++;
}
}
}
int main ()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
{
scanf("%d",&col[i]);
if(col[i]) ve[col[i]].push_back(i);
}
for(int i=;i<n;i++)
scanf("%d%d",&t1,&t2),Link(t1,t2);
DFS(,,),Decompose(,);
for(int i=;i<=k;i++)
{
vint v=ve[i]; int lca=*v.begin();
if(v.size()>)
{
vit it=++v.begin();
while(it!=v.end())
lca=LCA(lca,*it++);
}
vit it=v.begin();
while(it!=v.end())
Climb(*it++,lca,i);
}
Getans(,);
// for(int i=1;i<=n;i++)
// printf("%d %d %d\n",mar[i],dp[i][0],dp[i][1]);
printf("%d",dp[][]);
return ;
}
解题:CF1118F2 Tree Cutting (Hard Version)的更多相关文章
- Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】
任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per tes ...
- Codeforces 1118F1 Tree Cutting (Easy Version) (简单树形DP)
<题目链接> 题目大意: 给定一棵树,树上的点有0,1,2三中情况,0代表该点无色.现在需要你将这棵树割掉一些边,使得割掉每条边分割成的两部分均最多只含有一种颜色的点,即分割后的两部分不能 ...
- Codeforces Round #540 (Div. 3)--1118F1 - Tree Cutting (Easy Version)
https://codeforces.com/contest/1118/problem/F1 #include<bits/stdc++.h> using namespace std; in ...
- Tree Cutting (Hard Version) CodeForces - 1118F2 (树形DP,计数)
大意:给定树, 每个点有颜色, 一个合法的边集要满足删除这些边后, 每个连通块内颜色仅有一种, 求所有合法边集的个数 $f[x][0/1]$表示子树$x$中是否还有与$x$连通的颜色 对于每种颜色已经 ...
- Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp
题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...
- CodeForces 1118F2. Tree Cutting (Hard Version)
题目简述:给定$n \leq 3 \times 10^5$个节点的树,其中一部分节点被染色,一共有$k$种不同的颜色.求将树划分成 $k$ 个不相交的部分的方案数,使得每个部分中除了未染色的节点以外的 ...
- 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)
Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...
- BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏
3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 47 Solved: 37[ ...
- BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )
因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...
随机推荐
- 20155338《网络对抗》Exp3 免杀原理与实践
20155338<网络对抗>Exp3 免杀原理与实践 实验过程 一.免杀效果参考基准 Kali使用上次实验msfvenom产生后门的可执行文件,上传到老师提供的网址http://www.v ...
- Sagas模式
Sagas属于一个错误管理模式,也同时用于控制复杂事务的执行和回滚等.同时,Compensating-Transaction模式的的实现也是也是类似于Sagas策略的,可以对比参考一下. Sagas的 ...
- 执行力:Just Do It
执行力,最最关键的一点就是,立即去做,不要想太多. 当有一件事需要去做的时候,你的大脑肯定是接受到了"某种信号",比如来了一个灵感.受到一点启发.做某件事突然来了兴趣.或者想去探讨 ...
- flask+socketio+echarts3 服务器监控程序(基于后端数据推送)
本文地址:http://www.cnblogs.com/hhh5460/p/7397006.html 说明 以前的那个例子的思路是后端监控数据存入数据库:前端ajax定时查询数据库. 这几天在看web ...
- Linux环境中Qt程序的手工发布
Linux环境中Qt程序的手工发布
- Photoshop CS4破解方法
先在网上下载Photoshop CS4的版本,安装后按如下步骤操作即可. 激活码: 1330-1082-3503-2270-3738-6738 1330-1776-8671-6289-7706-291 ...
- SQL Server 全文搜索
SQL Server 的全文搜索(Full-Text Search)是基于分词的文本检索功能,依赖于全文索引.全文索引不同于传统的平衡树(B-Tree)索引和列存储索引,它是由数据表构成的,称作倒转索 ...
- Visual studio 2017中 Javascript对于Xrm对象模型没有智能提示的解决办法
Visual studio 2017中 Javascript对于Xrm对象模型没有智能提示的解决办法 先上个图.语法提示支持到 Microsoft Dynamics xRM API 8.2 也就是cr ...
- Kafka API: TopicMetadata
Jusfr 原创,转载请注明来自博客园 TopicMetadataRequest/TopicMetadataResponse 前文简单说过"Kafka是自描述的",是指其broke ...
- supervisor管理进程 superlance对进程状态报警
supervisor介绍 首先,介绍一下supervisor.Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linu ...