「WC2018」州区划分(FWT)
「WC2018」州区划分(FWT)
我去弄了一个升级版的博客主题,比以前好看多了。感谢 @Wider
不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了。
洛谷上不开 \(O_2\) 根本过不去,自带大常数被卡到 \(15\) 分。。。
首先题了读了很久,发现一个州的集合可以不连通。。。
我们可以 \(O(n^22^n)\) 检验每一个状态是否满足条件,用并查集即可。
\(f[S]\) 为状态 \(S\) 时的满意度之和,\(g[S]\) 当状态 \(S\) 为合法状态时为 \(sum_S^p\)
\]
然后这个东西可以用 \(or\) 卷积的 \(FWT\) 优化。我觉得出题人特地把数据范围出这么大应该是卡 \(O(3^n)\) 的枚举子集。
\(Code\ Below:\)
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n,m,p,lim,w[30],d[30],e[30],fa[30],bin[30],cnt[1<<21],sum[1<<21],inv[1<<21],f[22][1<<21],g[22][1<<21];
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int sub(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return 1ll*x*y-1ll*x*y/mod*mod;}
inline int fpow(int a,int b){
int ret=1;
for(;b;b>>=1,a=mul(a,a))
if(b&1) ret=mul(ret,a);
return ret;
}
inline void FWT(int *f,int n){
for(int len=1;len<n;len<<=1)
for(int i=0;i<n;i++)
if(i&len) f[i]=add(f[i],f[i^len]);
}
inline void IFWT(int *f,int n){
for(int len=1;len<n;len<<=1)
for(int i=0;i<n;i++)
if(i&len) f[i]=sub(f[i],f[i^len]);
}
inline int find(int x){
return (x==fa[x])?x:fa[x]=find(fa[x]);
}
inline bool check(int S){
if(cnt[S]<=1) return 0;
int tot=0;
for(int i=0;i<n;i++) fa[i]=i,d[i]=0;
for(int i=0;i<n;i++)
if(S&bin[i]){
sum[S]+=w[i];
for(int j=i+1;j<n;j++)
if((S&bin[j])&&(e[i]&bin[j])){
d[i]++;d[j]++;
if(find(i)!=find(j)) fa[fa[i]]=fa[j],tot++;
}
}
sum[S]=(p==0)?1:(p==1)?sum[S]:sum[S]*sum[S];
if(tot<cnt[S]-1) return 1;
for(int i=0;i<n;i++)
if((S&bin[i])&&(d[i]&1)) return 1;
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
lim=1<<n;bin[0]=1;
for(int i=1;i<=n;i++) bin[i]=bin[i-1]<<1;
for(int i=1;i<lim;i++) cnt[i]=cnt[i>>1]+(i&1);
int x,y;
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
x--;y--;
e[x]|=bin[y];e[y]|=bin[x];
}
for(int i=0;i<n;i++) scanf("%d",&w[i]);
for(int i=0;i<lim;i++){
g[cnt[i]][i]=check(i)?sum[i]:0;
inv[i]=fpow(sum[i],mod-2);
}
for(int i=0;i<=n;i++) FWT(g[i],lim);
f[0][0]=1;FWT(f[0],lim);
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++)
for(int k=0;k<lim;k++) f[i][k]=add(f[i][k],mul(f[j][k],g[i-j][k]));
IFWT(f[i],lim);
for(int k=0;k<lim;k++) f[i][k]=(cnt[k]==i)?mul(f[i][k],inv[k]):0;
if(i<n) FWT(f[i],lim);
}
printf("%d\n",f[n][lim-1]);
return 0;
}
「WC2018」州区划分(FWT)的更多相关文章
- 【LOJ】#2340. 「WC2018」州区划分
题解 学习一个全世界人都会只有我不会的东西 子集变换! 难道我要把这题当板子讲?等等这题好像是板...WC出板题好刺激啊= = 假装我们都做过HAOI2015的FMT题,我们都知道一些FMT怎么解决或 ...
- loj#2340. 「WC2018」州区划分
FWT&&FMT板子 #include<cstdio> #include<iostream> #include<cstring> #include& ...
- 【WC2018】州区划分(FWT,动态规划)
[WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ...
- UOJ348. 【WC2018】州区划分
UOJ348. [WC2018]州区划分 http://uoj.ac/problem/348 分析: 设\(g(S)=(\sum\limits_{x\in S}w_x)^p[合法]\) \(f(S)\ ...
- 「WC2018」即时战略
「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...
- loj2341「WC2018」即时战略(随机化,LCT/动态点分治)
loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...
- [WC2018]州区划分——FWT+DP+FST
题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...
- UOJ#348. 【WC2018】州区划分
原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 ...
- [WC2018]州区划分(FWT)
题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...
随机推荐
- Rabbitmq 与springboot 结合
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- Rabbitmq(5) 路由模式
设置路由键 发送者 package com.aynu.bootamqp.service; import com.aynu.bootamqp.commons.utils.Amqp; import com ...
- This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
- 一个类似于jq的小型库
本人写了一个类似于jq的小型库,不过只是写了部分方法而已.并没有jq那么全面,下面就介绍下有哪些方法可以使用 第一个是选择器, 选择器比较简单 只支持ID选择器 $(‘#id_name’) Class ...
- 使用Powershell实现计算机名称及IP地址修改
我的第一篇博客分享,写这个代码的用途是在公司Ghost完系统之后去修改本地计算机名称及IP 地址,用Powershell实现. 1. 代码第一部分,检查Powershell是否已管理员权限执行,如果不 ...
- springBoot拦截器的使用
拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可 ...
- vi 操作
vi 3种模式:1命令行模式,2插入模式,3末行模式 Vim启动后直接进入的是命令行模式,命令行模式顾名思义就是可以输入各种命令的意思, 1. 命令行下按i键进入“插入模式”,命令行下按:键进入“末行 ...
- hmtl div水平、垂直居中
最近写网页经常需要将div在屏幕中居中显示,遂记录下几个常用的方法,都比较简单.水平居中直接加上<center>标签即可,或者设置margin:auto;当然也可以用下面的方法 下面说两种 ...
- (转)C# Windows服务 弹出消息提醒框
出处:http://blog.csdn.net/donghui6116773/article/details/53467069 服务(Service)对于大家来说一定不会陌生,它是Windows 操作 ...
- PHP Laravel定时任务Schedule
前提:本文方法是利用Linux的crontab定时任务来协助实现Laravel调度(Mac也一样). 一.首先添加Crontab定时任务,这里只做简单介绍. 用命令crontab -e 添加如下内容 ...