解:有一个很显然的状压......

就设f[s]表示选的点集为s的时候所有方案的权值和。

于是有f[s] = f[s \ t] * (sum[t] / sum[s])P

这枚举子集是3n的。

然后发现这是子集卷积,参考资料

于是就FWT搞一下...看代码

 #include <bits/stdc++.h>

 typedef long long LL;
const int N = , M = , MO = ; struct Edge {
int v, u;
}edge[N * N]; int w[N], sum[M], cnt[M], n, P, lm, invsum[M], pw[M], in[N], fa[N];
int f[N][M], g[N][M];
bool vis[M]; int find(int x) {
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
} inline void out(int x) {
for(int i = ; i < n; i++) {
printf("%d", (x >> i) & );
}
return;
} inline void merge(int x, int y) {
fa[find(x)] = find(y);
return;
} inline int qpow(int a, int b) {
int ans = ;
while(b) {
if(b & ) ans = 1ll * ans * a % MO;
a = 1ll * a * a % MO;
b = b >> ;
}
return ans;
} inline int pow(int x) {
return P ? (P == ? x : 1ll * x * x % MO) : ;
} inline void FWT_or(int *a, int n, int f) {
for(int len = ; len < n; len <<= ) {
for(int i = ; i < n; i += (len << )) {
for(int j = ; j < len; j++) {
(a[i + len + j] += f * a[i + j]) %= MO;
if(a[i + len + j] < ) a[i + len + j] += MO;
}
}
}
return;
} int main() {
int m;
scanf("%d%d%d", &n, &m, &P); for(int i = , x, y; i <= m; i++) {
scanf("%d%d", &edge[i].v, &edge[i].u);
}
for(int i = ; i <= n; i++) scanf("%d", &w[i]);
lm = ( << n) - ; /// lm = 1111111111(2)
for(int i = ; i <= lm; i++) pw[i] = pw[i >> ] + ;
for(int s = ; s <= lm; s++) {
cnt[s] = cnt[s ^ (s & (-s))] + ;
vis[s] = ;
memset(in + , , n * sizeof(int));
for(int i = ; i <= n; i++) {
fa[i] = i;
}
for(int i = ; i <= m; i++) {
if(((s >> (edge[i].v - )) & ) && ((s >> (edge[i].u - )) & )) {
in[edge[i].v]++;
in[edge[i].u]++;
merge(edge[i].u, edge[i].v);
}
}
bool nol = ;
int temp = ;
for(int i = ; i <= n; i++) {
if(in[i] & ) {
vis[s] = ;
}
if((s >> (i - )) & ) {
(sum[s] += w[i]) %= MO;
if(!temp) {
temp = find(i);
}
else if(find(i) != temp) {
nol = ;
}
}
}
if(nol) vis[s] = ;
invsum[s] = qpow(sum[s], MO - );
if(vis[s]) {
g[cnt[s]][s] = pow(sum[s]);
}
} f[][] = ;
for(int i = ; i <= n; i++) {
FWT_or(g[i], lm + , );
}
FWT_or(f[], lm + , );
for(int i = ; i <= n; i++) {
for(int j = ; j <= i; j++) {
for(int s = ; s <= lm; s++) {
(f[i][s] += 1ll * f[i - j][s] * g[j][s] % MO) %= MO;
}
}
FWT_or(f[i], lm + , -);
for(int s = ; s <= lm; s++) {
f[i][s] = 1ll * f[i][s] * pow(invsum[s]) % MO;
}
if(i < n) FWT_or(f[i], lm + , );
}
printf("%d\n", f[n][lm]);
return ;
}

AC代码

UOJ#348 州区划分的更多相关文章

  1. UOJ #348 州区划分 —— 状压DP+子集卷积

    题目:http://uoj.ac/problem/348 一开始可以 3^n 子集DP,枚举一种状态的最后一个集合是什么来转移: 设 \( f[s] \) 表示 \( s \) 集合内的点都划分好了, ...

  2. [UOJ#348][WC2018]州区划分

    [UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...

  3. UOJ#348. 【WC2018】州区划分

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 ...

  4. UOJ348. 【WC2018】州区划分

    UOJ348. [WC2018]州区划分 http://uoj.ac/problem/348 分析: 设\(g(S)=(\sum\limits_{x\in S}w_x)^p[合法]\) \(f(S)\ ...

  5. 【WC2018】州区划分(FWT,动态规划)

    [WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ...

  6. [WC2018]州区划分——FWT+DP+FST

    题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...

  7. [WC2018]州区划分

    [WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...

  8. 「WC2018」州区划分(FWT)

    「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...

  9. P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT

    LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...

随机推荐

  1. Error: Invoke-customs are only supported starting with Android O (--min-api 26)

    项目报错: 完美解决: 在App下 gradle.build中Android标签中 添加以下内容: compileOptions { sourceCompatibility JavaVersion.V ...

  2. (办公)SpringBoot和swagger2的整合.

    因为开发项目的接口需要给app,小程序测试,所以用swagger. 1.pom.xml: <dependency><!--添加Swagger依赖 --> <groupId ...

  3. 【已解决】checkout 配置无效的问题可以进来看下

    在日常工作中,我们经常会遇到要更新一个项目,但是由于更改了配置,需要将这些配置commit或者checkout,但是有的同学不想commit怎么办呢,只能通过checkout,那么问题又来了,改了很多 ...

  4. 深入理解Mysql索引的底层数据结构 B+ Tree (1)

    关键字的个数等于路的个数减1. 一个二叉树节点可以存储4kb大小的数据,假如关键字是整型的一个关键字占用4byte,其他数据冗余4个字节 4 kb = 4*1024 byte = 4096 byte. ...

  5. AjaxPro2完整入门教程

    一.目录 简单类型数据传送(介绍缓存,访问Session等) 表类型数据传送 数组类型数据传送(包含自定义类型数据) 二.环境搭建 1.这里本人用的是VS2012. 2.新建一个空的Web项目(.NE ...

  6. zabbix忘记admin登录密码重置密码

    问题描述: 有时候忘记admin的密码了,因为账号太多 解决方案: 1.zabbix连接的是mysql数据库 [root@localhost /]# mysql -uroot -pAbc123 #-u ...

  7. 雨后清风教你如何在Windows 7中对硬盘进行分区

    磁盘分区是将硬盘驱动器分成多个逻辑单元.人们通常不会选择对硬盘进行分区,但它有很多好处.主要是,通过对磁盘进行分区,您可以将操作系统与数据分开,从而减少数据损坏的可能性. 磁盘分区方法 打开“计算机管 ...

  8. python 3.7 配置mysql数据库

    一. mysql驱动安装 1.mysqlclient(推荐使用)    2.pymysql 二.django操作数据库     1.django配置连接数据库         settings.py ...

  9. Dockerfile Volume指令与docker -v的区别

    在学习Dockerfile的过程中有个VOLUME命令,很多教程或书中说的是用来定义匿名卷的,其作用如下: 容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文 ...

  10. 第一节 anaconda+jupyter+numpy简单使用

    数据分析:是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律 数据分析三剑客:Numpy,Pandas,Matplotlib 一 Anaconda 1 下载 官网:http ...