CF891D Sloth
题意:给你一棵树,你选择删掉一条边,再加上一条边(也要保证为树),问最后树上的节点能够两两完美匹配的加删边方案数?
n<=5e5.
标程:
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int read()
{
int x=;char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (''<=ch&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x;
}
const int N=;
typedef long long ll;
int size[N],n,u,v;
ll ans;
vector<int> vec[N];
struct node{int a[][];}f[N],g[N];
vector<node> pre[N];
void init(node &x){x.a[][]=;x.a[][]=x.a[][]=x.a[][]=;}
node modi(node x,node y)
{
node c;
c.a[][]=x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*(y.a[][]+y.a[][]);
c.a[][]=x.a[][]*y.a[][]+x.a[][]*(y.a[][]+y.a[][])+x.a[][]*y.a[][]+x.a[][]*y.a[][];
return c;
}
node merge(node x,node y)
{
node c;
c.a[][]=x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][]+x.a[][]*y.a[][]+x.a[][]*y.a[][];
return c;
}
void dp1(int x,int fa)
{
size[x]=;init(f[x]);
if (fa!=-) vec[x].erase(find(vec[x].begin(),vec[x].end(),fa));//将fa删去,方便前后缀的处理
for (int i=;i<vec[x].size();i++)
{
int v=vec[x][i]; //注意内部定义
dp1(v,x);size[x]+=size[v];
f[x]=modi(f[x],f[v]);
}
}
void dp2(int x,int fa)
{
node cur;init(cur);
if (fa>) pre[x].push_back(modi(cur,g[x]));else pre[x].push_back(cur);
for (int i=;i<vec[x].size();i++)
pre[x].push_back(modi(pre[x].back(),f[vec[x][i]]));
for (int i=vec[x].size()-;i>=;i--)
{
int v=vec[x][i];
g[v]=merge(pre[x][i],cur);cur=modi(cur,f[v]);
dp2(v,x);
}
}
int main()
{
n=read();if (n&) return puts(""),;
for (int i=;i<n;i++) u=read(),v=read(),vec[u].push_back(v),vec[v].push_back(u);
dp1(,-);dp2(,-);
for (int i=;i<=n;i++)
if (f[i].a[][]&&g[i].a[][]) ans+=(ll)size[i]*(n-size[i]);
else ans+=(ll)(f[i].a[][]+f[i].a[][])*(g[i].a[][]+g[i].a[][]);
printf("%lld\n",ans);
return ;
}
易错点:1.转移式子要认真推。
2.注意函数内部定义变量。
3.将fa在vector中删去,方便前后缀寻址的对应。
题解:dp
把一条边删掉,树就分成了两个子树。要么各自匹配(这样怎么连都可以),要么连一条边后边的端点匹配,也就是两个子树在没有连边前各有一个点没有匹配。
f[i][0/1][0/1]表示以i为根的子树,根是否被匹配,子树中是否恰有一个点未被匹配的未匹配点的选法数。
g表示i为根的子树外的部分的答案(以fa[i]为根)。正反dp两遍后统计答案即可。
CF891D Sloth的更多相关文章
- sloth——算法工程师标注数据的福音
一般算法工程师做标注,都要先开发个标注工具,无非下面几个选项: 1.mfc,C#,优点是交互界面友好,开发难度适中,缺点是没法跨平台 2.matlab,优点是可以跨平台,开发难度非常低,缺点是速度慢. ...
- Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.
Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.七宗罪:暴食.贪婪.懒惰.暴怒.傲慢.色欲.妒忌.
- Codeforces 891D - Sloth(换根 dp)
Codeforces 题面传送门 & 洛谷题面传送门 换根 dp 好题. 为啥没人做/yiw 首先 \(n\) 为奇数时答案显然为 \(0\),证明显然.接下来我们着重探讨 \(n\) 是偶数 ...
- Java Script 编码规范【转】
Java Script 编码规范 以下文档大多来自: Google JavaScript 编码规范指南 Idiomatic 风格 参考规范 ECMAScript 5.1 注解版 EcmaScript ...
- pickle序列化
通过pickle来序列化: # -*- coding: utf-8 -*- import pickle #-------------------序列化--------------------- zoo ...
- nullcon HackIM 2016 -- Programming Question 5
Dont blink your Eyes, you might miss it. But the fatigue and exhaustion rules out any logic, any wil ...
- C++ Primer Plus读书笔记
第五章 循环和关系表达式 1. 2.类别别名: (1) #define FLOAT_POINTER float * FLOAT_POINTER pa, pb; 预处理器置换将该声明转换成 flo ...
- Deep Learning in a Nutshell: History and Training
Deep Learning in a Nutshell: History and Training This series of blog posts aims to provide an intui ...
- javascript 函数式编程
编程范式 编程范式是一个由思考问题以及实现问题愿景的工具组成的框架.很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等. 函数式编程 ...
随机推荐
- 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp
目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...
- (转)HashSet<T>类
转载于:http://www.importnew.com/6931.html HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复 ...
- 10.2 External interrupt/event controller (EXTI)
EXTI控制器的主要特点如下: 每个中断/事件线上的独立触发器和掩码 每个中断行的专用状态位 生成最多20个软件事件/中断请求 脉冲宽度小于APB2时钟周期的外部信号检测. 每条中断线路的专用状态位生 ...
- Codeforces 1163A - Eating Soup
题目链接:http://codeforces.com/problemset/problem/1163/A 题意:n 只猫围成一圈,离开 m 只,最多剩下几组猫. 思路:当 n == m 即猫都离开时 ...
- 创建一个学生表student,默认的表空间为users,字段自定,同时为表的各个字段分别添加合适的约束,然后测试约束的验证状态。
create table student(id number(4) constraint prim_key primary key,name varchar(8) not null,sex varch ...
- sshpass批量分发ssh秘钥
首先安装sshpass: yum -y install sshpass 单条命令: sshpass -p“password” ssh-copy-id -i /root/.ssh/id_rsa.pub ...
- Flutter 集成到现有iOS工程
前沿 由于我司已经有自己的App,flutter属于技术引进的一部分,也不太可能重新启动一个项目,因此目前我们是将flutter模块形式注入我们的App之中.即:将flutter模块集成到现在有iOS ...
- CSIC_716_20191111【函数对象、名称空间、作用域、global 和nonlocal】
函数名是可以被引用,传递的是函数的内存地址.函数名赋值给变量后,只需要在变量后加上括号即可调用函数. 名称空间 内置名称空间:在python解释器中提前定义完的名字 全局名称空间:if.while.f ...
- 【JZOJ6370】基础 fake 练习题
description 装饰者坐在树荫下听着长者讲述以前的故事: 大神 yk 非常喜欢树,便钦点班里的 n 个小蒟蒻站在一棵 n 个点以 1 为根的树上,并且每个点上恰好有 1 个小蒟蒻. 大神 yk ...
- H5页面在手机上查看 使用手机浏览自己的web项目
参考:http://www.browsersync.cn/#install 首先全局安装BrowserSync : npm install -g browser-sync 其次在项目文件夹下运行: b ...