@atcoder - AGC024F@ Simple Subsequence Problem
@description@
给定由若干长度 <= N 的 01 字符串组成的集合 S。请找到长度最长的串 t(如果有多个选字典序最小的),使得存在 >= K 个 S 中的字符串,使得 t 是这些字符串的子序列。
@solution@
先看看怎么检验串 t 是否为某个串 s 的子序列:从前往后匹配,贪心地找最前面一个能够匹配上的。
注意到匹配的过程可以建图:每个种类的串 s 建点,向第一次出现的 0/1 对应的后缀连边。
每个点的连边是 O(1),因此假如把所有 <= N 的串建这个图,实际得到的图也不会很大。
于是就有一个思路:枚举 t,每次将 S 中的串对应的点在这个图上进行移动,看剩余的点是否依然 >= K 个。
看似会 TLE,然而可以修正一下:如果两个字符串走到了同一个点,下一次只移动这一个点即可。
看似还会 TLE,实际上可以过了。
因为每个长度为 p 的字符串会有 2^p 种可能性,而它继续往下匹配只会剩下 2^(N-p) 种匹配可能。因此每一个 p 都是 O(2^N) 的复杂度。
因此总复杂度为 O(N*2^N) (应该是吧,没有认真算过)。
@accepted code@
#include <cstdio>
int ch[2][1<<22], id[22][1<<21], cnt;
void get() {
id[0][0] = (cnt++), ch[0][id[0][0]] = ch[1][id[0][0]] = -1;
for(int i=1;i<=20;i++) {
int t = (1 << i), k = (t >> 1);
for(int s=0;s<t;s++) {
id[i][s] = (cnt++);
int p = (s & k), q = (p ? 1 : 0);
ch[q][id[i][s]] = id[i-1][s^p];
ch[!q][id[i][s]] = ch[!q][id[i-1][s^p]];
}
}
}
int a[22][1<<22], siz[22], c[22][1<<22], num[22][1<<22];
int ans[22], N, K;
void dfs(int d, int s) {
if( ans[d] == -1 ) ans[d] = s;
for(int p=0;p<=1;p++) {
int tot = 0;
for(int i=0;i<siz[d];i++) {
int to = ch[p][a[d][i]];
if( to == -1 ) continue;
if( num[d + 1][to] == -1 )
num[d + 1][a[d + 1][siz[d + 1]] = to] = siz[d + 1], siz[d + 1]++;
tot += c[d][i], c[d + 1][num[d + 1][to]] += c[d][i];
}
if( tot >= K ) dfs(d + 1, (s << 1) | p);
for(int i=0;i<siz[d + 1];i++)
num[d + 1][a[d + 1][i]] = -1, c[d + 1][i] = 0;
siz[d + 1] = 0;
}
}
char s[1<<21];
int main() {
scanf("%d%d", &N, &K), get();
for(int i=0;i<=N;i++)
for(int j=0;j<cnt;j++)
num[i][j] = -1;
for(int i=0;i<=N;i++) {
scanf("%s", s);
int t = (1 << i);
for(int j=0;j<t;j++) {
if( s[j] == '1' )
num[0][a[0][siz[0]] = id[i][j]] = siz[0], c[0][num[0][id[i][j]]]++, siz[0]++;
}
ans[i] = -1;
}
dfs(0, 0);
for(int i=N;i>=0;i--) {
if( ans[i] != -1 ) {
for(int j=i-1;j>=0;j--)
putchar(((ans[i] >> j) & 1) + '0');
puts(""); return 0;
}
}
}
@details@
事实证明再怎么精打细算还是有想象之外的越界危险。
还不如直接数组开大 2 倍。
@atcoder - AGC024F@ Simple Subsequence Problem的更多相关文章
- [题解] [AGC024F] Simple Subsequence Problem
题目大意 有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解. 由于 \(S\ ...
- BZOJ 3489: A simple rmq problem
3489: A simple rmq problem Time Limit: 40 Sec Memory Limit: 600 MBSubmit: 1594 Solved: 520[Submit] ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- hdu4976 A simple greedy problem. (贪心+DP)
http://acm.hdu.edu.cn/showproblem.php?pid=4976 2014 Multi-University Training Contest 10 1006 A simp ...
- hdu 1757 A Simple Math Problem (乘法矩阵)
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HDU1757 A Simple Math Problem 矩阵快速幂
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- hdu------(1757)A Simple Math Problem(简单矩阵快速幂)
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- bzoj 3489: A simple rmq problem k-d树思想大暴力
3489: A simple rmq problem Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 551 Solved: 170[Submit][ ...
- SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治
Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...
随机推荐
- Sql Server数据库导入Excel、txt数据详解,新人必看
转自个人原创 https://blog.csdn.net/qq_15170495/article/details/104591606 数据库的要想导入数据,列的映射很是关键,只有列名匹配好,系统才知道 ...
- 蓝桥杯 试题 算法提高 宰羊 DP解决
问题描述 炫炫回了内蒙,肯定要吃羊肉啦,所有他家要宰羊吃. 炫炫家有N只羊,羊圈排成一排,标号1~N.炫炫每天吃掉一只羊(这食量!其实是放生啦),吃掉的羊的邻居会以为它被放生了,然后又会告诉他们的邻居 ...
- 剑指Offer之二进制中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 解法1:使用Integer.toBinanryString()返回int变量的二进制表示的字符串. [在Intege ...
- GDI泄漏排查经验零散总结
1.GDI对象以及释放方法: GDI对象 产生方法 销毁方法 位图(HBITMAP) CreateBitmap,CreateBitmapIndirect, CreateCompatibleBitmap ...
- Linux光盘yum源软件安装
关于Linux中的软件安装,有三种方法,个人认为比较方便的就是yum安装,有网的话比较简单,暂且不提.本文主要记录在没有外网的情况下,如何以本地光盘搭建yum源来实现yum安装. 主要包括以下几步: ...
- DDD之2领域概念
图中是暗黑领域,非常牛逼的技能. 背景 DDD中出现的名词: 领域,子领域,核心域,通用域,支撑域,限界上下文,聚合,聚合根,实体,值对象 都是关键概念,但是又比较晦涩,在开始DDD之前,搞清楚这些关 ...
- 01 . Redis简介及部署主从复制
简介 Remote Dictionary Server, 翻译为远程字典服务, Redis是一个完全开源的基于Key-Value的NoSQL存储系统,他是一个使用ANSIC语言编写的,遵守BSD协议, ...
- 分布式 ID 的 9 种生成方式
为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 什么是分布式ID? 拿MySQL数据库举个栗子: 在我们业务数据量不大的时候, ...
- 服务器ip地址 服务器ip登录方法
服务器是指保存有该网络中所有主机的域名和对应IP地址,并具有将域名转换为IP地址功能的服务器.其中域名必须对应一个IP地址,一个域名可以有多个IP地址,而IP地址不一定有域名. 简单的解释就是:服 ...
- 从SpringBoot源码分析 主程序配置类加载过程
1.@Import(AutoConfigurationPackages.Registrar.class) 初始SpringBoot 我们知道在SpringBoot 启动类上有一个@SpringBoot ...