uoj#348/洛谷P4221 [WC2018]州区划分(FWT)
全世界都会子集卷积就咱不会……全世界都在写\(FMT\)就咱只会\(FWT\)……
前置芝士
或运算\(FWT\)或者\(FMT\)
左转洛谷模板区,包教包会
子集卷积
定义:对于两个集合幂级数\(F,G\),它们的子集卷积\(H\)定义为$$H_S=\sum_{T\subseteq S}F_TG_{S-T}$$
简单来说就是两个下标要满足的条件为\(L\cap R=\varnothing\)且\(L\cup R=S\)
\(L\cup R=S\)就是个异或卷积的事儿,关键是\(L\cap R=\varnothing\)太麻烦了
转化一下,\(L\cap R=\varnothing\)等价于\(|L|+|R|=|S|\)
那么我们可以新加一维,设\(f_{i,S}\)表示集合大小为\(i\),集合为\(S\),那么只有在\(i=|S|\)的时候这才是个对的东西。一开始的时候,我们可以把所有的\(f_{|S|,S}\)赋值为原来的\(f(S)\)(\(g\)同理),然后不断枚举\(i\),做完\(FWT\)之后令\(h_{i,S}=\sum_{j=0}^if_{j,S}g_{i-j,S}\)。每个\(i\)做完后,把那些\(|S|\neq i\)的\(h_{i,S}\)清零就好了
如果不是很明白为什么的话,可以这样理解。首先对于所有的\(j<i\),\(f_j,g_j\)里面存的都是正确的值。根据\(FWT\)的性质,未清零之前\(h_{i,S}\)中每一个\(S\)都是由那些\(L\cup R=S\)的\(f_L\)和\(g_R\)得来的,只要除去那些\(|L|+|R|\neq |S|\)的,剩下的肯定正确
本题题解
设\(f_S\)为选点集合为\(S\)时的贡献之和,\(g_S\)当\(S\)是一个合法集合时为\({sum_S}^p\),当\(S\)不合法时为\(0\)
那么递推式就是$$f_S=\frac{1}{{sum_S}^p}\sum_{T\subset S}f_Tg_{S-T}$$
似乎有点眼熟……话说这个不就是个子集卷积么……
等会儿?这玩意儿是自己卷自己啊?
但我们发现这里每一个数只会被自己的子集卷到,于是我们依然可以枚举\(i\),那么所有\(|T|<|S|\)的\(f_{|T|,T}\)已经算好了,直接带进去卷就好了
另外,\(S\)是个合法集合就是说\(S\)不存在欧拉回路,那么\(S\)存在欧拉回路的充要条件就是\(S\)连通且每个点度数都是偶数,判一下就好了
所以咱真的不知道为啥大家都写\(FMT\),咱写\(FMT\)比\(FWT\)慢好多啊……
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=(1<<21)+5,P=998244353;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int sz[N],sum[N],inv[N],f[25][N],g[25][N],w[25],p[25],fa[25],deg[25],bin[25];
int lim,n,m,q,u,v;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dft(int *A){
for(R int mid=1;mid<lim;mid<<=1)
for(R int j=0;j<lim;j+=(mid<<1))
for(R int k=0;k<mid;++k)
A[j+k+mid]=add(A[j+k+mid],A[j+k]);
}
void idft(int *A){
for(R int mid=1;mid<lim;mid<<=1)
for(R int j=0;j<lim;j+=(mid<<1))
for(R int k=0;k<mid;++k)
A[j+k+mid]=dec(A[j+k+mid],A[j+k]);
}
int calc(R int S){
if(!q)return 1;
R int res=0;
fp(i,1,n)if(S>>(i-1)&1)res=add(res,w[i]);
return q&1?res:mul(res,res);
}
bool ck(R int S){
if(sz[S]==1)return 0;
int k=sz[S];
fp(i,1,n)deg[i]=0,fa[i]=i;
fp(i,1,n)if(S&(1<<i-1)){
sum[S]+=w[i];
fp(j,i+1,n)if((S&(1<<j-1))&&(p[i]&(1<<j-1))){
++deg[i],++deg[j];
if(find(i)!=find(j))fa[fa[i]]=fa[j],--k;
}
}
sum[S]=q==0?1:q==1?sum[S]:sum[S]*sum[S];
if(k>1)return true;
fp(i,1,n)if((S&(1<<i-1))&&(deg[i]&1))return true;
return false;
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read(),q=read(),lim=(1<<n);
fp(i,1,m)u=read(),v=read(),p[u]|=(1<<v-1),p[v]|=(1<<u-1);
fp(i,1,n)w[i]=read();
fp(i,1,lim-1)sz[i]=sz[i>>1]+(i&1);
fp(i,1,lim-1){
g[sz[i]][i]=ck(i)?sum[i]:0;
inv[i]=ksm(sum[i],P-2);
}
fp(i,0,n)dft(g[i]);
f[0][0]=1,dft(f[0]);
fp(i,1,n){
fp(j,0,i-1)fp(k,0,lim-1)f[i][k]=add(f[i][k],mul(f[j][k],g[i-j][k]));
idft(f[i]);
fp(k,0,lim-1)f[i][k]=sz[k]==i?mul(f[i][k],inv[k]):0;
if(i!=n)dft(f[i]);
}
printf("%d\n",f[n][lim-1]);
return 0;
}
uoj#348/洛谷P4221 [WC2018]州区划分(FWT)的更多相关文章
- [WC2018]州区划分——FWT+DP+FST
题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...
- P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT
LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...
- [WC2018]州区划分(FWT)
题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...
- [UOJ#348][WC2018]州区划分
[UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...
- [WC2018]州区划分
[WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...
- 洛谷P4047 [JSOI2010]部落划分题解
洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...
- [WC2018]州区划分(FWT,FST)
[WC2018]州区划分(FWT,FST) Luogu loj 题解时间 经典FST. 在此之前似乎用到FST的题并不多? 首先预处理一个子集是不是欧拉回路很简单,判断是否连通且度数均为偶数即可. 考 ...
- 洛谷P4220 [WC2018]通道(边分治+虚树)
题面 传送门 题解 代码不就百来行么也不算很长丫 虽然这题随机化贪心就可以过而且速度和正解差不多不过我们还是要好好学正解 前置芝士 边分治 米娜应该都知道点分治是个什么东西,而边分治,顾名思义就是对边 ...
- [WC2018]州区划分(状压,子集卷积)
[洛谷题面]https://www.luogu.org/problemnew/show/P4221 首先考虑判定一个子图是否合法: (1)连通:并查集判断即可. (2)没有欧拉回路:存在欧拉回路的条件 ...
随机推荐
- yum安装软件出错解决方法
造成yum下载安装时语法出错, 一般是由于python多个版本共存的原因.所以,只需将yum 设置文件固定python 版本,也就是python2 下面的操作能解决版本冲突问题. 1.sudo vim ...
- [2017-12-20]ElasticSearch 小记
介绍 ElasticSearch是一款搜索引擎中间件,因其强大的全文索引.查询统计能力和非常方便的全套基于Restful的接口,以及在自动分片.无停机升级扩容.故障转移等运维方面的高效性,逐渐成为中小 ...
- DOM的构建与优化
一.构建模块 HTML描述了一个页面的结构.浏览器会将它转换成一种他们能够理解的格式——文档对象模型(DOM),浏览器引擎有一段特殊的代码叫做解析器,将数据从一种格式转换成另外一种格式. 一个HTML ...
- Uncaught TypeError: Illegal invocation解决
jquery中报了这个错,仔细一看,有个使用ajax的地方,其中有个参数是从页面某个文本框获取的,本应该 $('#id').value ,被我写成了 $('id') .所以报错,目前已解决.
- linux应用之apache的源码安装(centos)
第一部分:前期准备 需要下载的东西 下载 Apache 源码包 下载地址: http://httpd.apache.org/download.cgi ...
- POJ 2503 Babelfish(map,字典树,快排+二分,hash)
题意:先构造一个词典,然后输入外文单词,输出相应的英语单词. 这道题有4种方法可以做: 1.map 2.字典树 3.快排+二分 4.hash表 参考博客:[解题报告]POJ_2503 字典树,MAP ...
- elasticsearch ——id字段说明,内部是_uid
_id field Each document indexed is associated with a _type (see the section called “Mapping Typesedi ...
- JavaMail API的应用
JavaMail API 是一个用于阅读.编写和发送电子消息的可选包(标准扩展),用来创建邮件用户代理(Mail User Agent,MUA)类型程序. JavaMail API 需要 JavaBe ...
- leetcode 304. Range Sum Query 2D - Immutable(递推)
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...
- 网络编程学习笔记-linux常用的网络命令
网络参数设置命令 所有时刻如果你想要做好自己的网络参数设置,包括IP参数.路由参数和无线网络等,就得要了解下面这些相关的命令才行.其中Route及ip这两条命令是比较重要的.当然,比较早期的用法,我们 ...