$bzoj2560$ 串珠子 容斥+$dp$
正解:容斥+$dp$
解题报告:
$umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多少种方案可以连成一张联通图
显然考虑容斥呗?设$f_i$表示状态为$i$的点连成联通图的合法方案,$g_i$表示状态为$i$的点随便连边的所有方案
显然$g_i$可以先预处理出来?就等于$\prod_{u,v\in i}a_{u,v}$.然后$f_i$就等于$g_i$减去不合法的数量.不合法数量显然就考虑枚举子集${i}'$,就等于$\sum f_{{i}'}\cdot g_{i-{i}'}$.
但是这样显然依然会有锅,即一个不合法方案会被枚举其包含的联通块次.为了保证不重不漏,就只用枚指定点的联通块大小,比较通常的做法就枚举最大/最小点的联通块大小,也就钦定${i}'$中包含了最大/最小的点
然后就做完了$QwQ$
$over$
因为一些不知名原因我本机$AC$,$BZOJ$上$WA$了(事实上是,$emacs\ AC$,$lemon\ WA$,$darkbzoj\ WA$,$QAQ$
但是我暂时懒得搞了先把代码放上来趴$kk$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define lf double
#define int long long
#define ll long long
#define gc getchar()
#define ri register int
#define rc register char
#define rb register bool
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define gdgs(i,x) for(ri i=x-lowbit(x);i;i-=lowbit(i)) const int N=,mod=;
int n,a[N][N],lg[<<N],tot,d[N],cnt;
ll g[<<N],f[<<N],re[N]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
} signed main()
{
freopen("2560.in","r",stdin);freopen("2560.out","w",stdout);
n=read();rp(i,,n-)rp(j,,n-)a[i][j]=read();tot=(<<n)-;rp(i,,n-)lg[<<i]=i;g[]=;
rp(i,,tot)
{ll tmp=;gdgs(j,i)tmp=1ll*tmp*(a[lg[lowbit(i)]][lg[lowbit(j)]]+)%mod;g[i]=g[i-lowbit(i)]*tmp%mod;}
rp(i,,tot)
{
cnt=;gdgs(j,i)d[cnt++]=lowbit(j);
rp(j,,(<<cnt)-)re[j]=re[j-lowbit(j)]|d[lg[lowbit(j)]],f[i]=(f[i]+f[i^re[j]]*g[re[j]])%mod;
f[i]=(g[i]-f[i]+mod)%mod;
}
printf("%lld\n",f[tot]);
return ;
}
随机推荐
- @atcoder - Japanese Student Championship 2019 Qualification - E@ Card Collector
目录 @description@ @solution@ @accepted code@ @details@ @description@ N 个卡片放在 H*W 的方格图上,第 i 张卡片的权值为 Ai ...
- 【HAOI2015】树上染色
[HAOI2015]树上染色 这题思路好神仙啊,首先显然是树形dp,f[i][j]表示在以i为根的子树中选j个黑点对答案的贡献(并不是当前子树最大值),dp时只考虑i与儿子连边的贡献.此时(i,son ...
- 网站域名加WWW与不加WWW区别
不知道站长童鞋们有没有注意到,很多网站在打开时,地址栏里的域名有的带有“www.”,而有的网站前面则没有带“www.”这其中有什么区别呢?作为一个新站长,我什么都不懂,就在百度上搜了一艘,也没找到一个 ...
- C#中的?操作符
一.1个?的用法 1. 表示可空数据类型,如 int? bool? 2. 跟在对象后,如该对象为null,则不会触发空值异常,且整个表达式返回null,如: string kk = "123 ...
- 割点(tarjan)
对于根来说,如果它有超过1棵子树,那么它是一个割点 对于非叶结点来说,如果它的某一个儿子没有回边能到达高于它的点,那么它是一个割点 叶节点不是割点 //洛谷3388 #include<algor ...
- C# 比较两张图片是否完全相同
本文演示如何比较两张图片是否完全相同. (注意:如果是比较两张图片是否相似,则比较复杂,涉及到机器学习) 方法一:把图片保存到内存流中,然后转化成 Base64 字符串进行比较 using Syste ...
- ArrayList中remove方法和set(null)的区别
在分析源码ArrayList.remove()时,偶然发现了一个疑惑的点,就是:源码也是将最后一个对象的引用指向null(源码:elementData[--size] = null; // clear ...
- Python--day43--mysql自增列之起始值和步长
对于自增: 1,查看字段,类型以及是否可以为空,默认值:desc t2; 2,查看表t2是怎么创建的show create table t2; (竖着看)查看表t2是怎么创建的show create ...
- H3C 最大跳数16导致网络尺度小
- python模块之模块导入
模块的导入 """ 模块的导入使用:模块导入一般都要放在代码的最上面 不同模块的导入顺序: 1 内置模块 2 扩展模块 3 自定义模块 """ ...