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 函数式编程
编程范式 编程范式是一个由思考问题以及实现问题愿景的工具组成的框架.很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等. 函数式编程 ...
随机推荐
- Comparison of FastText and Word2Vec
Comparison of FastText and Word2Vec Facebook Research open sourced a great project yesterday - fas ...
- HDU1501-Zipper-字符串的dfs
Given three strings, you are to determine whether the third string can be formed by combining the ch ...
- 使用反射机制,获取 ArrayList 的容量大小
本文所有说明及代码示例都是基于JDK 1.8 ArrayList 提供size()方法获取当前集合的元素数量,但无法知道当前集合的容量,翻看 ArrayList 的源代码,可以看到字段 elemen ...
- D3.js坐标轴的绘制方法、添加坐标轴的刻度和各比例尺的坐标轴(V3版本)
坐标轴(Axis) 坐标轴(Axis)在很多图表中都可见到,例如柱形图.折线图.散点图等.坐标轴由一组线段和文字组成,坐标轴上的点由一个坐标值确定.但是,如果使用SVG的直线和文字一笔一画的绘制坐 ...
- Ubuntu 最简单的方式安装chrome
1.指定安装目录如下: cd opt/ 2.下载包: sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current ...
- arm-linux-objdump 的使用
1. 查看静态库或.o 文件的组成文件 [arm@localhost gcc]$ armlinuxobjdump a libhello.a 2. 查看静态库或.o 文件的络组成部分的头部分 [a ...
- vim 命令行模式 操作指令
复制n行: nyy 粘贴:p 剪切(删除)n行: ndd 剪切 ( 删除 ) n个字符:nx 移动光标到第一行 : gg 移动光标到最后一行 : G 设置格式 :gg=G 返回上一次操作前(撤销 ...
- Asp.net MVC使用EasyNetQ操作RabbitMQ
Demo下载地址:https://download.csdn.net/download/u010312811/11259742 .Net下操作RabbitMQ最常用的SDK是RabbitMQ.Clie ...
- 【学术篇】SPOJ COT 树上主席树
这是学完主席树去写的第二道题_(:з」∠)_ 之前用树上莫队水过了COT2... 其实COT也可以用树上莫队水过去不过好像复杂度要带个log还是怎么样可能会被卡常数.. 那就orz主席吧.... 写了 ...
- python库之xgboost
一.安装 https://www.zhihu.com/question/46377605