LINK:州区划分

把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路.

充要条件有两个 联通 每个点度数为偶数.

预处理出所有状态.

然后设\(f_i\)表示组成情况为i的值.

枚举子集转移 可以发现利用FST进行优化.

FST怎么做?详见另一篇文章史上最详细FST解释

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000000000000ll
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 998244353
#define max(x,y) ((x)<(y)?y:x)
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=1<<21,maxn=22;
int n,m,p,maxx;
int f[maxn][MAXN],c[MAXN],g[maxn][MAXN],w[MAXN],in[MAXN];
int d[maxn],fa[maxn];
struct wy
{
int x,y;
}t[MAXN];
inline int getfather(int x){return x==fa[x]?x:fa[x]=getfather(fa[x]);}
inline int ksm(int b,int p)
{
int cnt=1;
while(p)
{
if(p&1)cnt=(ll)cnt*b%mod;
b=(ll)b*b%mod;p=p>>1;
}
return cnt;
}
inline void FWT(int *f,int op)
{
for(int len=2;len<=maxx+1;len=len<<1)
{
int mid=len>>1;
for(int j=0;j<=maxx;j+=len)
{
vep(0,mid,i)
{
if(op==1)f[i+j+mid]=(f[i+j+mid]+f[i+j])%mod;
else f[i+j+mid]=(f[i+j+mid]-f[i+j]+mod)%mod;
}
}
}
}
inline int pd(int x)
{
if(c[x]<=1)return 0;
int cnt=c[x];
rep(1,n,i)fa[i]=i,d[i]=0;
rep(1,m,i)
{
if(((1<<(t[i].x-1))&x)&&((1<<(t[i].y-1))&x))
{
d[t[i].x]^=1;d[t[i].y]^=1;
int xx=getfather(t[i].x);
int yy=getfather(t[i].y);
if(xx==yy)continue;
fa[xx]=yy;--cnt;
}
}
if(cnt!=1)return 1;
rep(1,n,i)if(d[i])return 1;
return 0;
}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(m);get(p);
rep(1,m,i)
{
int get(x),get(y);
t[i]=(wy){x,y};
}
rep(1,n,i)get(w[i]);
maxx=1<<n;--maxx;
rep(1,maxx,i)
{
int sum=0;c[i]=c[i>>1]+(i&1);
rep(1,n,j)if(i&(1<<(j-1)))sum+=w[j];
sum=ksm(sum,p);in[i]=ksm(sum,mod-2);
//cout<<pd(i)<<' '<<i<<endl;
//cout<<sum<<endl;
if(pd(i))g[c[i]][i]=sum;
//cout<<g[c[i]][i]<<endl;
}
rep(1,n,i)FWT(g[i],1);
f[0][0]=1;FWT(f[0],1);
rep(1,n,i)
{
vep(0,i,j)
rep(0,maxx,k)f[i][k]=(f[i][k]+(ll)f[j][k]*g[i-j][k])%mod;
FWT(f[i],-1);
rep(0,maxx,k)f[i][k]=(ll)f[i][k]*in[k]%mod;
FWT(f[i],1);
}
FWT(f[n],-1);
put(f[n][maxx]);
return 0;
}

P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT的更多相关文章

  1. uoj#348/洛谷P4221 [WC2018]州区划分(FWT)

    传送门(uoj) 传送门(洛谷) 全世界都会子集卷积就咱不会--全世界都在写\(FMT\)就咱只会\(FWT\)-- 前置芝士 或运算\(FWT\)或者\(FMT\) 左转洛谷模板区,包教包会 子集卷 ...

  2. [WC2018]州区划分(状压DP+FWT/FMT)

    很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...

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

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

  4. [WC2018]州区划分(FWT,FST)

    [WC2018]州区划分(FWT,FST) Luogu loj 题解时间 经典FST. 在此之前似乎用到FST的题并不多? 首先预处理一个子集是不是欧拉回路很简单,判断是否连通且度数均为偶数即可. 考 ...

  5. [WC2018]州区划分

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

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

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

  7. 【UOJ348】【WC2018】州区划分 状压DP FWT

    题目大意 给定一个\(n\)个点的无向图,对于每种 \(n\) 个点的划分\(\{S_1,S_2,\ldots,S_k\}\),定义它是合法的,当且仅当每个点都在其中的一个集合中且对于任何的\(i\i ...

  8. [WC2018]州区划分(FWT)

    题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...

  9. Luogu4221 WC2018州区划分(状压dp+FWT)

    合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方 ...

随机推荐

  1. Spark 两种方法计算分组取Top N

    Spark 分组取Top N运算 大数据处理中,对数据分组后,取TopN是非常常见的运算. 下面我们以一个例子来展示spark如何进行分组取Top的运算. 1.RDD方法分组取TopN from py ...

  2. 状压DP之中国象棋

    题目 传送们 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方 ...

  3. mysql--数据插入覆盖和时间戳的问题

    1.数据插入问题 当我们insert数据时,插入datetime类型,此类型的字段,存储数据格式为:  YYYY-MM-DD,它支持的范围为'1000-01-01'到'9999-12-31',并且允许 ...

  4. Blazor带我重玩前端(三)

    写在前面 需要升级VS2019以及.NET Core到最新版(具体的最低支持,我已经忘了,总是越新支持的就越好),以更好的支持自己开发Blazor项目. WebAssembly 搜索Blazor模板 ...

  5. HBuilder生成证书

    一.安装jdk https://www.oracle.com/java/technologies/javase-downloads.html 二.打开CMD命令到JDK安装目录bin文件夹下 执行命令 ...

  6. day61 django入门(2)

    目录 一.数据的查.改.删 1 查 2 改 3 删 二.django orm中如何创建表关系 三.django请求生命周期流程图 四.路由层 1 无名分组 2 有名分组 3 两种分组不能混用,单个可以 ...

  7. Java面向对象详解-下

    一. static static:静态的,可以用来修饰属性.方法.代码块(或初始化块).内部类 static修饰属性(类变量): 由类创建的所有的对象,都共用这一个属性 当其中一个对象对此属性进行修改 ...

  8. javascript知识梳理之数据类型

    javascript基础知识(在javascript中 = 是赋值符号) 变量 合法的变量命名规则:大小写英文.数字. $ 和 _ 的组合,且不能用数字开头. var a; //声明变量 var s ...

  9. java 基本语法(十八)Lambda (五)Stream API

    1.Stream API的理解:1.1 Stream关注的是对数据的运算,与CPU打交道集合关注的是数据的存储,与内存打交道 1.2 java8提供了一套api,使用这套api可以对内存中的数据进行过 ...

  10. 01 flask源码剖析之werkzurg 了解wsgi

    01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...