【LOJ】#2340. 「WC2018」州区划分
题解
学习一个全世界人都会只有我不会的东西
子集变换!
难道我要把这题当板子讲?等等这题好像是板。。。WC出板题好刺激啊= =
假装我们都做过HAOI2015的FMT题,我们都知道一些FMT怎么解决或卷积的理论(似乎FMT本质就是FWT的或卷积方式)
子集变换是什么呢,就是把FMT带一个多项式
什么意思呢,就是我们需要
\(h_{S} = \sum_{T \subseteq S} g_{T}f_{S - T}\)
算h,怎么算,显然或卷积不成立啊,因为可能有交集
那么考虑到\(|S| + |S - T| = |S|\)绝对值符号指元素个数,也就是1的个数
我们就……套上一个多项式!
\(g_{T}x^{|T|}\)的\(g_{T}\)是有值的
这样我们对每个N都做一遍FMT,相乘之后做一遍IFMT,我们需要的就是\(h_{S}x^{|S|}\)
那么……我们再来看这道题
显然就是
\(dp_{S} = \frac{1}{g_{S}}\sum_{T \subseteq S}g_{T}dp_{S - T}\)
g就是集合里人数的总和的p次方
啥,自己和自己卷积……
我们处理的时候从dp[1 - N][S]开始处理,就是每次算好每一层的dp值,还原回来乘上前面的系数,再FMT回去
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
//#define ivorysi
#define MAXN 100005
#define eps 1e-7
#define mo 974711
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
const int64 MOD = 998244353;
int N,M,p;
int g[25][25],ind[25],cnt[1 << 21],w[25],fa[25];
int64 F[23][1 << 21],inv[1 << 21],dp[23][1 << 21];
bool vis[25];
int getfa(int x) {
return fa[x] == x ? x : fa[x] = getfa(fa[x]);
}
int64 fpow(int64 x,int64 c) {
int64 res = 1,t = x;
while(c) {
if(c & 1) res = res * t % MOD;
t = t * t % MOD;
c >>= 1;
}
return res;
}
int64 calc(int64 v) {
if(p == 0) return 1;
else if(p == 1) return v;
else return v * v % MOD;
}
void FMT(int64 *a,int64 ty) {
for(int i = 1 ; i < (1 << N) ; i <<= 1) {
for(int j = 0 ; j < (1 << N) ; ++j) {
if(j & i) a[j] = (a[j] + ty * a[j ^ i] + MOD) % MOD;
}
}
}
void Init() {
scanf("%d%d%d",&N,&M,&p);
int u,v;
for(int i = 1 ; i <= M ; ++i) {
scanf("%d%d",&u,&v);
g[u][v] = g[v][u] = 1;
}
for(int i = 1 ; i <= N ; ++i) scanf("%d",&w[i]);
for(int i = 1 ; i < (1 << N) ; ++i) cnt[i] = cnt[i - (i & -i)] + 1;
for(int S = 1 ; S < (1 << N) ; ++S) {
memset(vis,0,sizeof(vis));
memset(ind,0,sizeof(ind));
int sum = 0,v = 0;
for(int i = 1 ; i <= N ; ++i) {
fa[i] = i;
if((S >> i - 1) & 1) {
vis[i] = 1,sum += w[i];
if(v == 0) v = i;
}
}
for(int i = 1 ; i <= N ; ++i) {
if(!vis[i]) continue;
for(int j = i + 1 ; j <= N ; ++j) {
if(!vis[j]) continue;
if(g[i][j] == 1) {
fa[getfa(i)] = getfa(j);
++ind[i];++ind[j];
}
}
}
bool flag = 1;
for(int i = 1 ; i <= N ; ++i) {
if(vis[i]) {
if(ind[i] & 1) {flag = 0;break;}
if(getfa(v) != getfa(i)) {flag = 0;break;}
}
}
F[cnt[S]][S] = (flag ^ 1) * calc(sum);
inv[S] = fpow(calc(sum),MOD - 2);
}
}
void Solve() {
for(int i = 1 ; i <= N ; ++i) FMT(F[i],1);
dp[0][0] = 1;
FMT(dp[0],1);
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= i ; ++j) {
for(int S = 0 ; S < (1 << N) ; ++S) {
(dp[i][S] += dp[i - j][S] * F[j][S]) %= MOD;
}
}
FMT(dp[i],-1);
for(int S = 0 ; S < (1 << N) ; ++S) dp[i][S] = dp[i][S] * inv[S] % MOD;
FMT(dp[i],1);
}
FMT(dp[N],-1);
printf("%lld\n",dp[N][(1 << N) - 1]);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
【LOJ】#2340. 「WC2018」州区划分的更多相关文章
- loj#2340. 「WC2018」州区划分
FWT&&FMT板子 #include<cstdio> #include<iostream> #include<cstring> #include& ...
- 「WC2018」州区划分(FWT)
「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...
- LOJ 2339 「WC2018」通道——边分治+虚树
题目:https://loj.ac/problem/2339 两棵树的话,可以用 CTSC2018 暴力写挂的方法,边分治+虚树.O(nlogn). 考虑怎么在这个方法上再加一棵树.发现很难弄. 看了 ...
- @loj - 2339@ 「WC2018」通道
目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 11328 年,C 国的科学家们研发了一种高速传送通道,可以在很短的 ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
- Loj #3042. 「ZJOI2019」麻将
Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...
- Loj #2570. 「ZJOI2017」线段树
Loj #2570. 「ZJOI2017」线段树 题目描述 线段树是九条可怜很喜欢的一个数据结构,它拥有着简单的结构.优秀的复杂度与强大的功能,因此可怜曾经花了很长时间研究线段树的一些性质. 最近可怜 ...
- loj2341「WC2018」即时战略(随机化,LCT/动态点分治)
loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
随机推荐
- python---重点(设计模式)
前戏:设计模式简介 设计模式是面向对象设计的解决方案,是复用性程序设计的经验总结.(与语言无关,任何语言都可以实现设计模式) 设计模式根据使用目的的不同而分为创建型模式(Creational Patt ...
- zookeeper系列之:独立模式部署zookeeper服务
一.简述 独立模式是部署zookeeper服务的三种模式中最简单和最基础的模式,只需一台机器即可,独立模式仅适用于学习,开发和生产都不建议使用独立模式.本文介绍以独立模式部署zookeeper服务器的 ...
- awk例子
ls |awk -F . '{print $1}'|awk -F '-[0-9]' '{print $1}'
- [转载]Getting Started with ASP.NET vNext and Visual Studio 14
说在转载之前的话:ASP.NET框架之前不断做大,而vNext则是从头开始,对ASP.NET框架进行拆分并瘦身,面对不同的需求而更加灵活,各个拆分出来的模块更加轻量.vNext的出现,对ASP.NET ...
- 一个愚蠢的python逻辑语法错误
这个事情再次佐证了一个莫名其妙的现象背后一定会有一个愚蠢到无以复加的错误的真理. 写python单元测试的时候发现一个莫名其妙的问题: def xmlStandander(self,s): retur ...
- VS2010 项目属性的默认包含路径设置方法
VS2010 项目属性的默认包含路径设置方法 分类: c++小技巧2014-01-10 10:16 1358人阅读 评论(0) 收藏 举报 c++ 有两种方法可以设置vs2010的默认包含路径 方法一 ...
- Linux路径名和文件名最大长度限制
UNIX标准对路径名和文件名最大长度限制做出了说明,但其上限值在实际应用长过小,Linux在具体实现时提升了该上限,该限制在Linux的 /usr/include/linux/limits.h 中做出 ...
- 将网址url中的参数转化为JSON格式
网上方法很多,各种奇技淫巧,这里贴上一种较为正常的思路. 主要利用split对获取的字符串不断进行分割,最后获得所需要的格式. 代码如下 <!DOCTYPE html> <html ...
- ubuntu更新源列表
1. 备份源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup 2.修改更新源 打开源列表 sudo gedit /etc/ap ...
- 一步一步搭建 oracle 11gR2 rac + dg 之前传 (一)【转】
一步一步在RHEL6.5+VMware Workstation 10上搭建 oracle 11gR2 rac + dg 之前传 (一) 转自 一步一步搭建 oracle 11gR2 rac + dg ...