UOJ#348 州区划分


解:有一个很显然的状压......
就设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 州区划分的更多相关文章
- UOJ #348 州区划分 —— 状压DP+子集卷积
题目:http://uoj.ac/problem/348 一开始可以 3^n 子集DP,枚举一种状态的最后一个集合是什么来转移: 设 \( f[s] \) 表示 \( s \) 集合内的点都划分好了, ...
- [UOJ#348][WC2018]州区划分
[UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...
- UOJ#348. 【WC2018】州区划分
原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 ...
- UOJ348. 【WC2018】州区划分
UOJ348. [WC2018]州区划分 http://uoj.ac/problem/348 分析: 设\(g(S)=(\sum\limits_{x\in S}w_x)^p[合法]\) \(f(S)\ ...
- 【WC2018】州区划分(FWT,动态规划)
[WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ...
- [WC2018]州区划分——FWT+DP+FST
题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...
- [WC2018]州区划分
[WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...
- 「WC2018」州区划分(FWT)
「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...
- P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT
LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...
随机推荐
- Redis订阅与发布
发布与订阅模型在许多编程语言中都有实现,也就是我们经常说的设计模式中的一种--观察者模式.在一些应用场合,例如发送方并不是以固定频率发送消息,如果接收方频繁去咨询发送方,这种操作无疑是很麻烦并且不友好 ...
- bug管理工具之禅道的测试模块的使用
https://www.cnblogs.com/evablogs/p/6785017.html 角色:产品经理PO,项目经理PM,开发,测试 测试任务: bug: 1.维护bug视图模块:[测试]-[ ...
- Cs231n课堂内容记录-Lecture 8 深度学习框架
Lecture 8 Deep Learning Software 课堂笔记参见:https://blog.csdn.net/u012554092/article/details/78159316 今 ...
- .net 调用java service 代理类方法
通过Svcutil.exe 工具生成代理类调用 1.找到如下地址“C:\Windows\System32\cmd.exe” 命令行工具,右键以管理员身份运行(视系统是否为win7 而定) 2 ...
- Installing Supervisor and Superlance on CentOS
Installing Supervisor1 and Superlance2 on CentOS/RHEL/Fedora can be a little tricky, as the versions ...
- 替换空格[by Python]
题目: 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 1.使用python自带的repla ...
- [LeetCode] 9. 回文数
题目链接:https://leetcode-cn.com/problems/palindrome-number/ 题目描述: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都 ...
- java 服务端I/O非阻塞实现05
/** * 非阻塞IO多线线程服务端 * 当一个任务进入多线程,这个任务线程需要处理接收信息.发送信息.因而发生I/O阻塞问题 * 利用selector可以实现异步 * */ public class ...
- 使用exec和sp_executesql动态执行SQL语句(转载)
当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...
- JS 面向对象 ~ 继承的7种方式
前言: 继承 是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承 和 实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在 ...