uoj348【WC2018】州区划分
题目链接
直接讲吨吨吨给的标准做法吧。记\(f(i,j)\)表示各个州(可以重叠)的城市数量之和为i,这些州的并集为j的方案数,反正若有两个州之间有交集最后的\(|j|\)会不等于\(i\)。有
\(f(i,s)=\sum_{s1} \sum_{s2}[s1|s2==s] \ f(i-|s2|,s1)*can(s2) (\frac{vals(s2)}{vals(s)})^p\)
\(f(i,s)*vals(s)^p=\sum_j \sum_{|s2|=j} \sum_{s1} [s1|s2==s]\ f(i-j,s1)*can(s2) *vals(s2)^p\)
记\(g(|s|,s)\)表示\(can(s)*vals(s)^p\),先在最开始DWT所有的g,枚举i,j,然后卷一下\(f_{i-j}\)与\(g_j\),只要在dp的过程中一直保持f是已经DWT了的,卷积的复杂度就只有\(O(2^n)\),记得\(f_i\)算完以后要IDWT一下乘上\(vals(s)^{-p}\)再DWT。复杂度\(O(n^22^n)\)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define ln putchar('\n')
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
inline int read()
{
char ch=getchar();int g=1,re=0;
while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
return re*g;
}
typedef long long ll;
typedef pair<int,int> pii;
const int N=25;
const int mod=998244353;
inline ll qpow(ll a,int n)
{
ll ans=1;
for(;n;n>>=1,a=a*a%mod) if(n&1) ans=ans*a%mod;
return ans;
}
void FWT(int *a,int n,ll f)
{
for(int step=1;step<n;step<<=1)
for(int j=0;j<n;j+=(step<<1))
for(int k=j;k<j+step;++k)
{
int x=a[k],y=a[k+step];
a[k+step]=(y+f*x+mod)%mod;
}
}
int head[N],cnt=0;
struct node
{
int to,next;
}e[N*N];
inline void add(int x,int y)
{
e[++cnt]=(node){y,head[x]}; head[x]=cnt;
e[++cnt]=(node){x,head[y]}; head[y]=cnt;
}
int val[N],n,m,vals[1<<21|1],deg[N],fa[N];
bool can[1<<21|1];
pii edg[N*N];
inline int find(int x)
{
if(fa[x]!=x) return fa[x]=find(fa[x]);
return fa[x];
}
int f[23][1<<21|1],g[23][1<<21|1];
void wj()
{
#ifndef ONLINE_JUDGE
freopen("walk.in","r",stdin);
freopen("walk.out","w",stdout);
#endif
}
int main()
{
wj();
n=read(); m=read(); int p=read();
for(int i=1;i<=m;++i)
{
int x=read(),y=read();
add(x,y);
edg[i]=pii(x,y);
}
for(int i=1;i<=n;++i) val[i]=read();
int tot=1<<n;
for(int s=0;s<tot;++s)
{
int all=0;
for(int i=1;i<=n;++i) if(s&(1<<i-1)) vals[s]+=val[i],all++;
vals[s]=qpow(vals[s],p);
for(int i=1;i<=n;++i) fa[i]=i,deg[i]=0;
for(int i=1;i<=m;++i) if((s&(1<<edg[i].fi-1))&&(s&(1<<edg[i].se-1)))
{
deg[edg[i].fi]++; deg[edg[i].se]++;
int r1=find(edg[i].fi),r2=find(edg[i].se);
if(r1!=r2) all--;
fa[r1]=r2;
}
can[s]=1;
if(all!=1) continue;
for(int i=1;i<=n;++i) if(s&(1<<i-1))
if(deg[i]&1) {can[s]=1;break;}
else can[s]=0;
}
f[0][0]=1;
for(int s=0;s<tot;++s)
g[__builtin_popcount(s)][s]=can[s]*vals[s],vals[s]=qpow(vals[s],mod-2);
FWT(f[0],tot,1);
for(int i=1;i<=n;++i) FWT(g[i],tot,1);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=i;++j)
{
for(int k=0;k<tot;++k) f[i][k]=(f[i][k]+1ll*f[i-j][k]*g[j][k])%mod;
}
if(!p) continue;
FWT(f[i],tot,-1);
for(int k=0;k<tot;++k) f[i][k]=1ll*f[i][k]*vals[k]%mod;
FWT(f[i],tot,1);
}
FWT(f[n],tot,-1);
printf("%d\n",f[n][tot-1]);
return 0;
}
uoj348【WC2018】州区划分的更多相关文章
- UOJ348 WC2018 州区划分 状压DP、欧拉回路、子集卷积
传送门 应该都会判欧拉回路吧(雾 考虑状压DP:设\(W_i\)表示集合\(i\)的点的权值和,\(route_i\)表示点集\(i\)的导出子图中是否存在欧拉回路,\(f_i\)表示前若干个城市包含 ...
- [WC2018]州区划分——FWT+DP+FST
题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...
- [WC2018]州区划分
[WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...
- [UOJ#348][WC2018]州区划分
[UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...
- [WC2018]州区划分(FWT,FST)
[WC2018]州区划分(FWT,FST) Luogu loj 题解时间 经典FST. 在此之前似乎用到FST的题并不多? 首先预处理一个子集是不是欧拉回路很简单,判断是否连通且度数均为偶数即可. 考 ...
- P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT
LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...
- [WC2018]州区划分(FWT)
题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...
- Luogu4221 WC2018州区划分(状压dp+FWT)
合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方 ...
- LOJ2340 [WC2018] 州区划分 【FMT】【欧拉回路】
题目分析: 这题是WC的题??? 令 $g[S] = (\sum_{x \in S}w_x)^p$ $h[S] = g[S]$如果$S$不是欧拉回路 $d[S] = \frac{f[S]}{g[All ...
- [WC2018]州区划分(状压DP+FWT/FMT)
很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...
随机推荐
- CVI中调用数据库的几点..
1.各类开发工具开发的程序调用数据库,有两种方式:ADO和ODBC. 2.以ODBC方式访问SQL数据库,必须在电脑管理工具----ODBC管理器 中配置TCP/IP项(IP1.IP2.IP3.IPA ...
- JavaScript 权威指南-学习笔记(一)
本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! ## JavaScript 权威指南-学 ...
- 【Java面试】这道互联网高频面试题难住了80%的程序员?索引什么时候失效?
"索引什么时候失效?" 面试过程中,突如其来的一个问题,是不是有点懵? 没关系,关注我,面试不迷路. 我是Mic,一个工作了14年的Java程序员. 索引失效涉及到的知识点非常多, ...
- ETCD快速入门-03 常用命令
3. ETCD 常用命令 etcdctl是一个命令行的客户端,它提供了一些命令,可以方便我们在对服务进行测试或者手动修改数据库内容.etcdctl与kubectl和systemctl的命令原理 ...
- Luogu1919 【模板】A*B Problem升级版(FFT)
简单的\(A*B\) \(Problem\),卡精度卡到想女装 #include <iostream> #include <cstdio> #include <cstri ...
- 基于bert_bilstm_crf的命名实体
前言 本文将介绍基于pytorch的bert_bilstm_crf进行命名实体识别,涵盖多个数据集.命名实体识别指的是从文本中提取出想要的实体,本文使用的标注方式是BIOES,例如,对于文本虞兔良先生 ...
- 简单概述因特网(Internet)
学习目的 了解 Internet 的概念,区别因特网与互联网. 了解 Internet 的基本结构. 了解 Internet 的发展历史. Internet 概念 因特网(Internet)是全球性的 ...
- 一个监控工具monit
最近看了一个问题,monit监控在读取配置文件之后,访问的文件是残留在容器中的,导致认为服务异常,其实一开始容器启动,并没有对应的服务. [root@10-36-235-119.fin-wealth- ...
- 2022CISCN-satool
2022CISCN-satool 打国赛的时候自己还并不了解LLVM PASS pwn,前几天正好学习了一下LLVM PASS pwn,于是就顺便来复现一下这道题目. 首先找到二进制文件的重写函数的主 ...
- CF1368G Shifting Dominoes (线段树)
题面 有一个 n × m n\times m n×m 的棋盘,被 1 × 2 1\times 2 1×2 的骨牌覆盖,保证 2 ∣ n × m 2|n\times m 2∣n×m. 现在你需要执行以下 ...