[WC2018]州区划分(状压,子集卷积)
[洛谷题面]https://www.luogu.org/problemnew/show/P4221
首先考虑判定一个子图是否合法:
(1)连通:并查集判断即可。
(2)没有欧拉回路:存在欧拉回路的条件是度数均为偶数,计算度数判断即可。
容易想到进行状压DP,设 \(F[S]\) 表示选取点集 \(S\) 的答案。
\]
直接按上式暴力,复杂度为 \(O(3^n)\),可以通过 \(15pts\)。
然而注意到这是一个类似子集卷积的形式,显然是可以FWT优化的,而由于卷积式中有本身,故可以按照集合大小从小到大计算即可。
时间复杂度 \(O(n^22^n)\),实现时要注意寻址的连续否则容易被卡常。一个子集卷积85分
#include<cstdio>
typedef long long ll;
const int N=22,M=1<<21,P=998244353;
int fpow(int a,int b)
{
ll w(1),o(a);
while(b) {
if(b&1) w=w*o%P;
o=o*o%P;
b>>=1;
}
return w;
}
int Inv(int x)
{
return fpow(x,P-2);
}
int n,m,k,len,w[N],sum[M],sk[M],ski[M],mark[M],f[N],deg[N],dp[N][M],g[N][M];
struct edge {
int u,v;
}e[N*N];
inline int fp(int i,int j)
{
return (i>>(j-1))&1;
}
inline void upd(int&x, int y)
{
x=(x+y)%P;
}
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
int ck(int D)
{
int y=0;
for(int i=1; i<=n; i++)
if(fp(D,i))
{
int x=find(i);
if(!y) y=x;
if(x^y) return 1;
}
for(int i=1; i<=n; i++)
if(fp(D,i))
{
if(deg[i]&1)
return 1;
}
return 0;
}
inline void re(int &x) { x+=x>>31&P; }
void fwt(int *s,int o)
{
for(int l=1; l<len; l<<=1)
for(int i=0; i<len; i+=l<<1)
for(int j=i; j<i+l; j++)
if(!o) re(s[j+l]+=s[j]-P);
else re(s[j+l]-=s[j]);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
len=1<<n;
for(int i=1; i<=m; i++)
scanf("%d %d",&e[i].u,&e[i].v);
for(int i=1; i<=n; i++)
scanf("%d",&w[i]);
for(int i=1; i<len; i++)
{
for(int j=1; j<=n; j++)
if(fp(i,j))
upd(sum[i],w[j]);
sk[i]=fpow(sum[i],k);
ski[i]=Inv(sk[i]);
}
for(int i=1; i<len; i++)
{
for(int j=1; j<=n; j++)
if(fp(i,j)) f[j]=j,deg[j]=0;
for(int j=1; j<=m; j++)
if(fp(i,e[j].u) && fp(i,e[j].v))
{
deg[e[j].u]++;
deg[e[j].v]++;
int fu=find(e[j].u),fv=find(e[j].v);
if(fu^fv) f[fu]=fv;
}
mark[i]=ck(i);
}
for(int i=1; i<len; i++)
if(mark[i])
g[__builtin_popcount(i)][i]=sk[i];
for(int i=0; i<=n; i++) fwt(g[i],0);
dp[0][0]=1;
fwt(dp[0],0);
for(int i=1; i<=n; i++)
{
for(int k=0; k<i; k++)
for(int j=1; j<len; j++)
re(dp[i][j]+=(ll)dp[k][j]*g[i-k][j]%P-P);
fwt(dp[i],1);
for(int j=1; j<len; j++)
if(dp[i][j]) dp[i][j]=(ll)dp[i][j]*ski[j]%P;
if(i==n)
{
printf("%d",dp[n][len-1]);
break;
}
fwt(dp[i],0);
}
return 0;
}
[WC2018]州区划分(状压,子集卷积)的更多相关文章
- UOJ348 WC2018 州区划分 状压DP、欧拉回路、子集卷积
传送门 应该都会判欧拉回路吧(雾 考虑状压DP:设\(W_i\)表示集合\(i\)的点的权值和,\(route_i\)表示点集\(i\)的导出子图中是否存在欧拉回路,\(f_i\)表示前若干个城市包含 ...
- [WC2018]州区划分(状压DP+FWT/FMT)
很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...
- UOJ #348 州区划分 —— 状压DP+子集卷积
题目:http://uoj.ac/problem/348 一开始可以 3^n 子集DP,枚举一种状态的最后一个集合是什么来转移: 设 \( f[s] \) 表示 \( s \) 集合内的点都划分好了, ...
- 【UOJ348】【WC2018】州区划分 状压DP FWT
题目大意 给定一个\(n\)个点的无向图,对于每种 \(n\) 个点的划分\(\{S_1,S_2,\ldots,S_k\}\),定义它是合法的,当且仅当每个点都在其中的一个集合中且对于任何的\(i\i ...
- [WC2018]州区划分(FWT,FST)
[WC2018]州区划分(FWT,FST) Luogu loj 题解时间 经典FST. 在此之前似乎用到FST的题并不多? 首先预处理一个子集是不是欧拉回路很简单,判断是否连通且度数均为偶数即可. 考 ...
- [WC2018]州区划分
[WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...
- [WC2018]州区划分——FWT+DP+FST
题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...
- [UOJ#348][WC2018]州区划分
[UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...
- Luogu4221 WC2018州区划分(状压dp+FWT)
合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方 ...
随机推荐
- 【网易官方】极客战记(codecombat)攻略-地牢-橱柜里的骷髅
关卡连接: https://codecombat.163.com/play/level/cupboards-of-kithgard 谁知道什么样的恐怖事情潜伏在 Kithgard 的橱柜里? 简介: ...
- Abp.core中在应用层获取HttpContext对象
实际IHttpContextAccessor对象已经在底层实现了自动的依赖注入,只需要在应用层引入Microsoft.AspNetCore.Http,然后在构造函数中依赖注入即可. /// <s ...
- vuex中怎么直接获取state中的值,以及computed的使用注意
1,直接用$store对象获取store对象,再进一步获取state属性..... 2, 3,computed computed是计算属性,他不可以直把值直接存入data中,因此不能像data一样直接 ...
- 微信小程序使用wxParse实现接入富文本编辑
简介 微信小程序中比如活动说明,简介这样的图文介绍说明页面,后台通常配置成富文本编辑框,由后台直接输入内容,然后在小程序界面展现. 但是富文本编辑提取到内容是html格式的,写法与小程序的wxml并不 ...
- Spring - MVC - 修改 Java 类后, 触发重启
1. 概述 学习 Spring MVC 下, 如何可控的触发重启 2. 背景 学习 Spring 场景 有些时候, 改完类, 需要重启 之前有听说, Spring MVC 可以自动重启 于是想, 尝试 ...
- * ./common/http.js in ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-opt
vue项目报错如下,找到原因之后,其实超简单,请看: 原来是引入文件路径出现问题,想起刚刚引入了一个文件,一修改,果然药到病除! ----------------------------------- ...
- Django 报错no sucn column: OpretionalError
1.报错原因:新增的字段未能同步数据库 2.解决办法:删除整个数据库,然后重新编译,然后over 1.rm -rf db.sqlites3 #删除数据库 2.rm -rf cmdb/migrarion ...
- springboot去除内嵌tomcat和打包在tomcat中运行需要做的步骤
去除内嵌tomcat和添加jsp依赖 去除内嵌tomcat 在springboot启动依赖中去除内嵌tomcat <dependency> <groupId>org.sprin ...
- LeetCode | No.2 两数相加
题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序的方式存储的,并且它们的每个节点只能存储一位数字.如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- mapreduce课上实验
今天我们课上做了一个关于数据清洗的实验,具体实验内容如下: 1.数据清洗:按照进行数据清洗,并将清洗后的数据导入hive数据库中: 2.数据处理: ·统计最受欢迎的视频/文章的Top10访问次数 (v ...