[cf1326F]Wise Men
对答案序列求一个高维后缀和,再通过差分将其解出,后者复杂度为$o(n2^{n})$
对于求后缀和后的结果,即01序列仅要求1处有边(不要求0处没有边),那么也即要求将原图划分为若干条长度给定且没有公共点的链
不妨先去枚举链的长度,假设为$\{l_{1},l_{2},...,l_{m}\}$,要求满足$l_{1}\le l_{2}\le ...\le l_{m}$且$\sum_{i=1}^{m}l_{i}=n$,记其对应的方案数为$P(n)$即为A000041,也即有$P(18)=385$
下面,问题即要求出对应的方案数,并加到需要贡献的状态上——
状压dp求出$f_{S}$表示$S$中的点构成链的排列数,时间复杂度为$o(n^{2}2^{n})$
构造$g_{i,S}=\begin{cases}0&(|S|\ne i)\\f_{S}&(|S|=i)\end{cases}$,不难发现方案数即为$(\bigcirc_{i=1}^{m}g_{l_{i}})_{V}$(其中$\circ$为或卷积,$V$为点集),先预处理出$g_{i}$做FWT的结果,再$o(2^{n})$求出乘积在$V$处的值,时间复杂度为$o(n^{2}2^{n}+P(n)2^{n})$
对于其有贡献的状态,即将$\{l_{i}\}$重新排列后不同的序列,注意到每一个状态最多统计一次,因此暴力枚举所有排列(不重复)的复杂度也仅为$o(P(n)2^{n})$
综上,总复杂度为$o(n^{2}2^{n}+P(n)2^{n})$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N (1<<18)
4 #define L 19
5 #define ll long long
6 vector<int>v;
7 int n,cnt[N],vis[L];
8 ll f[N][L],g[L][N],S[N],SS[L][N],ans[N];
9 char s[L][L];
10 void FWT(ll *a){
11 for(int i=0;i<n;i++)
12 for(int j=0;j<(1<<n);j++)
13 if (j&(1<<i))a[j]+=a[j^(1<<i)];
14 }
15 void get_per(int k,int S,ll s){
16 if (k==v.size()){
17 ans[S]+=s;
18 return;
19 }
20 int lst=0;
21 for(int i=0;i<v.size();i++)
22 if ((!vis[i])&&(lst!=v[i])){
23 vis[i]=1,lst=v[i];
24 get_per(k+1,((S<<v[i])|((1<<v[i]-1)-1)),s);
25 vis[i]=0;
26 }
27 }
28 void dfs(int k,int lst){
29 if (!k){
30 ll s=0;
31 for(int i=0;i<(1<<n);i++)
32 if ((n-cnt[i])&1)s-=S[i];
33 else s+=S[i];
34 get_per(0,0,s);
35 return;
36 }
37 memcpy(SS[k],S,sizeof(S));
38 for(int i=lst;i<=k;i++){
39 v.push_back(i);
40 for(int j=0;j<(1<<n);j++)S[j]*=g[i][j];
41 dfs(k-i,i);
42 v.pop_back();
43 memcpy(S,SS[k],sizeof(S));
44 }
45 }
46 int main(){
47 scanf("%d",&n);
48 for(int i=0;i<n;i++)scanf("%s",s[i]);
49 for(int i=0;i<(1<<n);i++)cnt[i]=cnt[i>>1]+(i&1);
50 for(int i=0;i<n;i++)f[1<<i][i]=1;
51 for(int i=1;i<(1<<n);i++)
52 for(int j=0;j<n;j++)
53 if (i&(1<<j)){
54 g[cnt[i]][i]+=f[i][j];
55 for(int k=0;k<n;k++)
56 if (((i&(1<<k))==0)&&(s[j][k]=='1'))f[i|(1<<k)][k]+=f[i][j];
57 }
58 for(int i=1;i<=n;i++)FWT(g[i]);
59 for(int i=0;i<(1<<n);i++)S[i]=1;
60 dfs(n,1);
61 n--;
62 for(int i=0;i<n;i++)
63 for(int j=0;j<(1<<n);j++)
64 if (j&(1<<i))ans[j^(1<<i)]-=ans[j];
65 for(int i=0;i<(1<<n);i++)printf("%lld ",ans[i]);
66 printf("\n");
67 return 0;
68 }
[cf1326F]Wise Men的更多相关文章
- Codeforces 1326F2 - Wise Men (Hard Version)(FWT+整数划分)
Codeforces 题目传送门 & 洛谷题目传送门 qwq 这题大约是二十来天前 AC 的罢,为何拖到此时才完成这篇题解,由此可见我是个名副其实的大鸽子( 这是我上 M 的那场我没切掉的 F ...
- Bible
001 Love your neighbor as yourself. 要爱人如己.--<旧·利>19:18 002 Resentment kills a foo ...
- MFC9.0 Outlook控件的标题显示无法修改
这是我在开发中遇到的问题,现记录下来,以便帮助你们. 不想看废话的可以只看最后三行,但你会错过很多. 俗话说的好啊,"Wise men learn by other men's mistak ...
- Do not go gentle into that good night
Do not go gentle into that good night By:Dylan Thomas Do not go gentle into that good night,Old ag ...
- MFC9.0 Outlook控件的标题显示无法改动
这是我在开发中遇到的问题,现记录下来,以便帮助你们. 不想看废话的能够仅仅看最后三行,但你会错过非常多. 俗话说的好啊,"Wise men learn by other men's mist ...
- June 7. 2018 Week 23rd Thursday
Half is worse than none at all. 一知半解比一无所知更痛苦. From Westworld. If we go looking for the truth, get th ...
- PMP模拟考试-1
1. A manufacturing project has a schedule performance index (SPI) of 0.89 and a cost performance ind ...
- time is always a factor, time is always now!!!!
https://www.linkedin.com/pulse/time-always-now-joe-alderman ---------------------------------------- ...
- 快速沃尔什变换&快速莫比乌斯变换小记
u1s1 距离省选只剩 5 days 了,现在学新算法真的合适吗(( 位运算卷积 众所周知,对于最普通的卷积 \(c_i=\sum\limits_{j+k=i}a_jb_k\),\(a_jb_k\) ...
随机推荐
- CentOS 7.9+19c单实例静默安装
一.环境准备 二.解压文件 三.文件配置 四.安装 五.相关调整 六.打补丁 一.环境准备0.依赖包安装 rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE} (%{A ...
- ArrayList和LinkedList、及Vector对比分析
ArrayList和LinkedList 底层结构 两者的差别主要来自于底层的数据结构不同,ArrayList是基于数组实现的,LinkedList是基于双链表实现的. 接口实现 LinkedList ...
- OGG-如何只同步最近某个时间范围的数据
一.需求,某客户希望使用OGG只同步时间大于2021-02-01日期之后的数据变换 需求如标题所示,如何使用OGG进行配置? 客户环境需要同步的表有几百G,表数据太大了;如果同步所有数据,目标库空间存 ...
- C 输入输出函数
流 就C程序而言,所有的I/O操作只是简单地从程序移入或移出字节的事情.这种字节流便称为流( stream ). 绝大多数流是完全缓存的,这意味着"读取"和"写入&quo ...
- Windows内核开发-9-32位和64位的区别
Windows内核开发-9-32位和64位的区别 32位的应用程序可以完美再64位的电脑上运行,而32位的内核驱动无法再64位的电脑上运行,或者64位的驱动无法在32位的应用程序上运行.这是为什么呢. ...
- 使用docker部署nginx并配置https
我只有一台服务器,但我想在这台服务器上运行多个项目,怎么办? 总不能靠加端口区分吧? 百度和Google是个好东西,于是我找到了答案,使用nginx. 通过nginx,我可以给我的一台服务器配置两个域 ...
- 80. 删除有序数组中的重复项 II
题目 给你一个有序数组 nums ,请你原地删除重复出现的元素(不需要考虑数组中超出新长度后面的元素),使每个元素最多出现两次 ,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入 ...
- kivy画个半圆
from kivy.uix.boxlayout import BoxLayout from kivy.app import App class BoxLayoutWidget(BoxLayout): ...
- nssm.exe使用方法
nssm no-sucking service manager 1. 安装服务命令 nssm install <servicename> nssm install <servicen ...
- 离线状态迁移Anaconda虚拟环境
离线状态迁移Anaconda虚拟环境 同样是项目需求,需要布署的服务器上的Anaconda安装到了普通账户下 而后续所有的内容都需要通过root账户进行操作,而服务器已经布署,联网比较麻烦 本文提出, ...