全网唯一一篇容斥题解

Description

Solution

看到这个题,大部分人想的是状压dp

但是我是个蒟蒻没想到,就用容斥切掉了。

并且复杂度比一般状压低,

(其实这个容斥的算法,提出来源于ywy_c_asm)

(然而我知道了这个算法,竟然和他写的不一样,而且比他跑的快)

进入正题:

我们需要统计恰好满足匹配k个的情况。

那么,我们可以先找出来,恰好满足n个,n-1,n-2。。。k个的情况。

分别记为ans[i]

ans[i]怎么算呢?

先给出公式:

ans[i]=cal(i)-∑C(j,i)×ans[j] 其中,i+1<=j<=n

cal(i)表示,从n个中任意选择i个,对于所有选择的情况,的方案数的和。

cal(i)可以dfs暴力C(n,i)枚举,每次统计答案。计入tot

void dfs(int x,int has){
if(x==n+){
if(has!=up) return;
ll lp=;
for(int j=;j<=len;j++){
las=-;
for(int i=;i<=up;i++){
if(a[mem[i]][j]!='?'){
if(las==-){
las=a[mem[i]][j]-'a';
}
else if(las!=a[mem[i]][j]-'a') return;
}
}
if(las==-)lp=(lp*)%mod;
}
(tot+=lp)%=mod;
return;
}
if(has<up) {
mem[++cnt]=x;
dfs(x+,has+);
mem[cnt--]=;
}
if(n-x>=up-has) dfs(x+,has);
}

至于后面减去的部分。就是容斥的内容了。

大家可以自己画一个韦恩图理解一下。

这里有一个例子:n=4

现在我们要算ans[2],也就是恰好匹配2个的T的方案数

就是黄色的部分。

红色的数字是这个区域被算cal(i)的次数。

可见,三个点的重复区域,由于有C(3,2)种方法选到,所以会被算C(3,2)次。

所以减去所有的ans[3]即可。

其他情况同理。

最后输出ans[1]

组合数打表。

理论复杂度:
O(n×len×2^15)

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
const int M=;
const int mod=;
char a[N][M];
int len;
int n,t,k;
int mem[N],cnt;
ll ans[N];
ll c[N][N];
ll sum;
ll tot;//tot measures
int up;//choose
int las;
void dfs(int x,int has){//dfs计算tot
if(x==n+){
if(has!=up) return;
ll lp=;
for(int j=;j<=len;j++){
las=-;
for(int i=;i<=up;i++){
if(a[mem[i]][j]!='?'){
if(las==-){
las=a[mem[i]][j]-'a';
}
else if(las!=a[mem[i]][j]-'a') return;//两个字符不一样,无合法方案
}
}
if(las==-)lp=(lp*)%mod;//如果都是‘?’可以随便填,否则只有一种
}
(tot+=lp)%=mod;
return;
}
if(has<up) {
mem[++cnt]=x;
dfs(x+,has+);
mem[cnt--]=;
}
if(n-x>=up-has) dfs(x+,has);
} void clear(){
memset(ans,,sizeof ans);
sum=;
len=;
}
int main()
{
for(int i=;i<=N-;i++){
c[i][]=;
for(int j=;j<=i;j++){
c[i][j]=(c[i-][j-]+c[i-][j])%mod;
}
}
scanf("%d",&t);
while(t--){
clear();//清空数组,其实没有必要
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%s",a[i]+);
}
len=strlen(a[]+);//长度 for(int i=n;i>=k;i--){//ans[i]计算
tot=;up=i;
dfs(,);
sum=;
for(int j=i+;j<=n;j++){//容斥的处理
(sum+=c[j][i]*ans[j])%=mod;
}
ans[i]=(tot-sum+mod)%mod;
}
printf("%lld\n",ans[k]);
}
return ;
}

[SDOI2009]Bill的挑战——全网唯一 一篇容斥题解的更多相关文章

  1. [BZOJ3523][Poi2014]KLO-Bricks——全网唯一 一篇O(n)题解+bzoj最优解

    Description 有n种颜色的砖块,第i种颜色的砖块有a[i]个,你需要把他们放成一排,使得相邻两个砖块的颜色不相同,限定第一个砖块的颜色是start,最后一个砖块的颜色是end,请构造出一种合 ...

  2. 【BZOJ1879】[SDOI2009]Bill的挑战(动态规划)

    [BZOJ1879][SDOI2009]Bill的挑战(动态规划) 题面 BZOJ 洛谷 题解 本来还想着容斥来着,这个数据范围直接暴力就好.设\(f[i][S]\)表示当前填到了第\(i\)位,和\ ...

  3. bzoj千题计划207:bzoj1879: [Sdoi2009]Bill的挑战

    http://www.lydsy.com/JudgeOnline/problem.php?id=1879 f[i][j] 表示匹配了i个字符,匹配字符串的状态为j的方案数 枚举下一个字符是什么 计算加 ...

  4. 【BZOJ1879】[Sdoi2009]Bill的挑战 状压DP

    [BZOJ1879][Sdoi2009]Bill的挑战 Description Input 本题包含多组数据.  第一行:一个整数T,表示数据的个数.  对于每组数据:  第一行:两个整数,N和K(含 ...

  5. bzoj 1879: [Sdoi2009]Bill的挑战

    题目链接 bzoj 1879: [Sdoi2009]Bill的挑战 题解 n<=15,装压吧 对所有字符串进行装压 可以预处理一个数组can[i][j]表示所有的字符串中,有哪些可以在第i位匹配 ...

  6. [bzoj1879][Sdoi2009]Bill的挑战_动态规划_状压dp

    Bill的挑战 bzoj-1879 Sdoi-2009 题目大意: 注释:$1\le t \le 5$,$1\le m \le 15$,$1\le length \le 50$. 想法: 又是一个看数 ...

  7. [LuoguP2167][SDOI2009]Bill的挑战_容斥原理/状压dp

    Bill的挑战 题目链接:https://www.luogu.org/problem/P2167 数据范围:略. 题解: 因为$k$特别小,想到状压. 状压的方式也非常简单,就是暴力枚举. 但是会不会 ...

  8. 【[SDOI2009]Bill的挑战】

    一看题解好像全是状压DP,那么我就来补充一个容斥写法吧 乍一看,好像是水题,枚举选哪k个串,然后判断 1,如果这k个串中至少两个串某位置确定且不相同,答案显然为02,如果这个位置只被有且仅有一个串确定 ...

  9. bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)

    Description  Input 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. Output ...

随机推荐

  1. 20155311高梓云《网络对抗》逆向及Bof基础

    20155311高梓云<网络对抗>逆向及Bof基础 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任 ...

  2. 异常 java.lang.IllegalArgumentException: Result Maps collection already contains value

    这是因为用了一次以上(多次)mbg导致sql映射文件堆积导致的异常,删除对应的sql映射文件,然后重新生成即可. Caused by: java.lang.IllegalArgumentExcepti ...

  3. Spring Boot(十二):Spring Boot 如何测试打包部署

    有很多网友会时不时的问我, Spring Boot 项目如何测试,如何部署,在生产中有什么好的部署方案吗?这篇文章就来介绍一下 Spring Boot 如何开发.调试.打包到最后的投产上线. 开发阶段 ...

  4. 【中间件】Redis 实战之主从复制、高可用、分布式

    目录 简介 持久化 主从复制 高可用 Redis-Sentinel .NET Core开发 分布式 Redis-Cluster 配置说明 常见问题 简介 本节内容基于 CentOS 7.4.1708, ...

  5. Microsoft Dynamics CRM 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)

    背景 经常有某个汇总子表的数量到主表的总数量,或者汇总子表的总价到主表的总价这种需求. 传统的做法: 1.就是为每个子表实体单独写成一个插件,但是这样不好复用. 2.主表的汇总字段是汇总货币类型,但是 ...

  6. linux AB web 性能测试工具

    ab(选项)(参数) 选项 -A:指定连接服务器的基本的认证凭据: -c:指定一次向服务器发出请求数: -C:添加cookie: -g:将测试结果输出为“gnuolot”文件: -h:显示帮助信息: ...

  7. package.json 中 npm 依赖包版本前的符号的意义

    版本的格式 major.minor.patch:主版本号.次版本号.修补版本号 patch:修复bug,兼容老版本 minor:新增功能,兼容老版本 major:新增功能,不兼容老版本 version ...

  8. springmvc 事务回滚说明

    Spring中的@Transactional(rollbackFor = Exception.class)属性详解 序言 今天我在写代码的时候,看到了.一个注解@Transactional(rollb ...

  9. Test Cases

    对于mode1 1 路径下一个空文件夹       结果:生成一个空的txt 2路径下一个文件夹内包含一个txt内容为abd(最基本的一个单词) 3路径下一个空文件夹一个txt,txt内容为以不同符号 ...

  10. 20135323符运锦----第三周:构建一个简单的Linux系统MenuOS

    相关知识点 1.arch目录 占据相当庞大的空间,X86目录下代码需要重点关注. 2.init目录 内核启动的相关代码基本都在此目录下,内含MAIN.C,文件中START_KERNEL是整个LINUX ...