题目传送门

  传送门I

  传送门II

题目大意

  有一个$n$个点的完全图,每个点的权值是$[0, 2^{m})$中的随机整数,两点间的边的权值是两点点权的异或和,问它的最小异或生成树的边权和的期望。

  考虑求最大异或生成树的分治做法,每次按最高位分成$V_0,V_1$两个集合(如果不行,那么这一层就不管)。

  然后再中间选一条最小边连接两个集合。两个集合分别再分治下去。

  现在我们希望求到中间这条最小边的边权的期望。

  直接求不好求,考虑换个方式统计。

  设$h_{n,m,bit,lim}$表示在第$bit + 1$位将图分成$X,Y$两个集合,其中$|X| = n, |Y| = m$,两个集合间的所有边的边权都大于等于$lim$的方案数(或概率)。

  转移的时候讨论一下

  • $lim$在第$bit$位为0

    • 如果$X,Y$中的点在$bit$位,一个集合中全为0,另一个集合中全为1,那么剩下的位可以任意填。
    • 否则枚举$X,Y$中分别有多少个点在第$bit$位为1,然后将集合又分为$X_0, X_1, Y_0, Y_1$,显然最小边连在$X_0, Y_0$之间或者$X_1,Y_1$之间,这是一个子问题,可以通过这个子问题的答案转移,再乘上组合数。
  • $lim$在第$bit$位为1
    • 此时$X,Y$中的点在$bit$位一定满足一个集合中全为0,另一个集合中全为1,直接通过它转移。

  统计期望或每种情况的边权和的时候做一个和就求出来了。

  设$f_{i, j}$表示有一个$i$个点的完全图,每个点的权值是$[0, 2^{j})$中的随机整数时的所有方案的答案和。

  显然能通过枚举$X_1$集合的大小来转移。

  复杂度令人绝望(据说常数小就能卡过去)。但是$n,m$都比较小,打个表交上去就过了。

Code

 #include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
typedef bool boolean; const int N = , M = , S = << M;
const int Mod = ; int add(int a, int b) {
return ((a += b) >= Mod) ? (a - Mod) : (a);
} int sub(int a, int b) {
return ((a -= b) < ) ? (a + Mod) : (a);
} int mul(int a, int b) {
return a * 1ll * b % Mod;
} int qpow(int a, int p) {
int pa = a, rt = ;
for ( ; p; p >>= , pa = mul(pa, pa))
if (p & )
rt = mul(rt, pa);
return rt;
} int inv(int a, int n) {
return qpow(a, n - );
} int n, m;
int f[N][N];
int comb[N][N];
int pow2[N * M];
int h[N][N][M][S]; inline void init() {
scanf("%d%d", &n, &m);
comb[][] = ;
for (int i = ; i <= n; i++) {
comb[i][] = comb[i][i] = ;
for (int j = ; j < i; j++)
comb[i][j] = add(comb[i - ][j - ], comb[i - ][j]);
}
pow2[] = ;
for (int i = ; i <= (n + ) * (m + ) + ; i++)
pow2[i] = add(pow2[i - ], pow2[i - ]);
} int dp(int n, int m, int bit, int lim) {
if (!bit)
return !lim;
if (!n || !m)
return pow2[(n + m) * bit];
int& rt = h[n][m][bit][lim];
if (~rt)
return rt;
if ((lim >> (bit - )) & ) {
rt = dp(n, m, bit - , lim ^ ( << (bit - )));
rt = add(rt, rt);
} else {
rt = pow2[(n + m) * (bit - ) + ];
for (int x = ; x <= n; x++)
for (int y = ; y <= m; y++) {
if ((!x && y == m) || (!y && x == n))
continue;
int a = dp(x, y, bit - , lim);
int b = dp(n - x, m - y, bit - , lim);
rt = add(rt, mul(mul(a, b), mul(comb[n][x], comb[m][y])));
}
}
return rt;
} int g(int n, int m, int bit) {
int rt = ;
for (int i = ; i < pow2[bit]; i++)
rt = add(rt, dp(n, m, bit, i));
// cerr << n << " " << m << " " << rt << " " << bit << '\n';
return rt;
} inline void solve() {
memset(h, -, sizeof(h));
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
int& val = f[i][j];
val = add(f[i][j - ], f[i][j - ]);
for (int cnt = , tmp; cnt < i; cnt++) {
tmp = mul(f[cnt][j - ], pow2[(i - cnt) * (j - )]);
tmp = add(tmp, mul(f[i - cnt][j - ], pow2[cnt * (j - )]));
tmp = add(tmp, g(cnt, i - cnt, j - ));
tmp = add(tmp, pow2[(i + ) * (j - )]);
// printf("tmp %d %d %d= %d\n", i, j, cnt, tmp);
val = add(val, mul(tmp, comb[i][cnt]));
}
// printf("f[%d][%d] = %d\n", i, j, f[i][j]);
}
for (int i = ; i <= n; i++) {
for (int j = ; j <= m; j++) {
printf("\tf[%d][%d] = %d;\n", i, j, mul(f[i][j], inv(pow2[i * j], Mod)));
}
}
} int main() {
freopen("young.txt", "w", stdout);
init();
solve();
return ;
}

bzoj 4770 图样 - 概率与期望 - 动态规划的更多相关文章

  1. NOIP 2016 换教室 (luogu 1850 & uoj 262) - 概率与期望 - 动态规划

    题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq i \leq n1≤ ...

  2. poj 2096 Collecting Bugs - 概率与期望 - 动态规划

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  3. poj 3744 Scout (Another) YYF I - 概率与期望 - 动态规划 - 矩阵快速幂

      (Another) YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into th ...

  4. BZOJ 3270: 博物馆 概率与期望+高斯消元

    和游走挺像的,都是将概率转成期望出现的次数,然后拿高斯消元来解. #include <bits/stdc++.h> #define N 23 #define setIO(s) freope ...

  5. BZOJ 3566 [SHOI2014]概率充电器 ——期望DP

    期望DP. 补集转化,考虑不能被点亮的情况, 然后就是三种情况,自己不能亮,父亲不能点亮它,儿子不能点亮它. 第一次计算比较容易,第二次计算的时候需要出去第一次的影响,因为一条线只能传导一次 #inc ...

  6. 【题解】亚瑟王 HNOI 2015 BZOJ 4008 概率 期望 动态规划

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4008 一道不简单的概率和期望dp题 根据期望的线性性质,容易想到,可以算出每张卡的期望伤害, ...

  7. 【BZOJ3566】概率充电器(动态规划)

    [BZOJ3566]概率充电器(动态规划) 题面 BZOJ Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: "采用全新纳米级加工 ...

  8. BZOJ_3270_博物馆_(高斯消元+期望动态规划+矩阵)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3270 \(n\)个房间,刚开始两个人分别在\(a,b\),每分钟在第\(i\)个房间有\(p[ ...

  9. 概率及期望DP小结

    资源分享 26 个比较概率大小的问题 数论小白都能看懂的数学期望讲解 概念 \(PS\):不需要知道太多概念,能拿来用就行了. 定义 样本(\(\omega\)):一次随机试验产生的一个结果. 样本空 ...

随机推荐

  1. 深入理解iostat

    前言 iostat算是比较重要的查看块设备运行状态的工具,相信大多数使用Linux的同学都用过这个工具,或者听说过这个工具.但是对于这个工具,引起的误解也是最多的,大多数人对这个工具处于朦朦胧胧的状态 ...

  2. 【Python基础】lpthw - Exercise 44 继承与组合

    一.继承 原则:大部分使用继承的场合都可以用组合取代或者简化,而多重继承则需要不惜一切的避免. 1. 什么是继承 继承:用于指明一个类的大部分或者全部功能都是从一个父类获得的.此时,父类的实例的所有动 ...

  3. 异想-天开 python---while、for、if-else 循环学习

    for循环: for i in range(10): # i循环10次 print('------',i) for j in range(10): print(j) if j > 2 : bre ...

  4. PHPstorm 2017激活

    网上看了很多,有用没几个.特别亲身试验了下.有一个有用的.摘录下来.备忘. 感谢该篇博文的作者.https://blog.csdn.net/veloi/article/details/71307942 ...

  5. java-类、对象

    1.类和对象: 类是抽象的,通常不能直接使用 对象是具体的,根据类来创建对象. 2.如何定义一个类:成员变量.成员方法 成员变量:直接定义在类中,在方法外面 成员方法:去掉static 关键字,其他和 ...

  6. spring-boot mybatis配置

    接着我们的spring boot项目,spring boot如何使用mybatis访问数据库呢? 个人习惯使用mapper接口和xml配置sql,从pom.xml入手 1.1 添加依赖 <dep ...

  7. Modelsimobjects空白无显示问题和ISim仿真时出现空白

    困扰朕长达一周的问题得以解决!!!!! 发生这种情况的根源是win10自带的防火墙的问题.只有关闭防火墙,再重新打开软件进行仿真就能出现正常的仿真界面. 关闭防火墙的方法为:控制面板>>系 ...

  8. MongoDB系列----查

    开启查询: db.getMongo().setSlaveOk() 查版本: db.servion(); db.serverBuildInfo(); db.serverStatus().storageE ...

  9. Ubuntu16.04重新安装MySQL数据库

    安装之前先检查mysql是否卸载干净 dpkg --list|grep mysql 如果没有卸载干净请看上篇文章将mysql卸载干净 Ubuntu16.04彻底卸载MySQL 开始安装 可以直接默认安 ...

  10. 微信小程序如何实现点击链接跳转到手机自带浏览器

    最近遇到一个需求.公司有一个业务,制作的小程序需要跳出微信打开一个指定的我们自己的页面,拿到这个需求后我们团队分开去找资料研究方案,通过微信的开发文档.腾讯的第三方开发文档我们都查阅过资料但是最终只找 ...