@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的更多相关文章

  1. [题解] [AGC024F] Simple Subsequence Problem

    题目大意 有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解. 由于 \(S\ ...

  2. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

  3. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  4. hdu4976 A simple greedy problem. (贪心+DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4976 2014 Multi-University Training Contest 10 1006 A simp ...

  5. hdu 1757 A Simple Math Problem (乘法矩阵)

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  6. HDU1757 A Simple Math Problem 矩阵快速幂

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  7. hdu------(1757)A Simple Math Problem(简单矩阵快速幂)

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. 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][ ...

  9. SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

    Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...

随机推荐

  1. php IE中文乱码

    echo mb_convert_encoding("你是我的朋友", "big5", "GB2312"); 详细出处参考:http://ww ...

  2. 我的excel是2003版本的,里边有sheet1、sheet2两个工作表,当使用GetOleDbSchemaTable获取表Schema时,结果是4个,分别为: sheet1 sheet1$ sheet2 sheet2$

    原帖地址:http://bbs.csdn.net/topics/310230098 ---------------------------------------------------------- ...

  3. blazor wasm访问非本地的restful service

    准备工作 blazor wasm正式版发布了!在尝试使用的过程中,发现几个小坑,跟大家分享一下,希望有所帮助. 我是通过keycloak来保护blazor和service的,如何保护service请参 ...

  4. codeforce E. Fire背包

    E. Fire time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  5. springboot中yml常用配置

    server: port: 8080 spring: datasource: #数据源配置 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc: ...

  6. Tortoise svn 基础知识

    1 不跟踪文件.文件夹 1.1  文件.文件夹已经被svn跟踪 将本地文件.文件夹删除(windows删除文件的删除,快捷键是shift+delete),然后执行svn  update 将服务器同步到 ...

  7. lin-cms-dotnetcore.是如何方法级别的权限控制的?

    方法级别的权限控制(API级别) Lin的定位在于实现一整套 CMS的解决方案,它是一个设计方案,提供了不同的后端,不同的前端,而且也支持不同的数据库 目前官方团队维护 lin-cms-vue,lin ...

  8. KNIME快速入门指南

    一.介绍  KNIME Analytics Platform是用于创建数据科学应用程序和服务的开源软件.KNIME直观,开放,不断整合新的开发,使人们可以理解数据,设计数据科学工作流程和可重用组件. ...

  9. dsPIC33EP单片机的PPS(外设引脚选择)

    利用dsPIC33EP单片机进行can通信的时候用到引脚复用 引脚复用通过查询数据手册: C1RX的寄存器为RPINR26.C1RXR=(设置为需要用到的引脚) 引脚设置为输入(C1RX),TRIS= ...

  10. Channels集成到Django消息实时推送

    channel架构图 InterFace Server:负责对协议进行解析,将不同的协议分发到不同的Channel Channel Layer:频道层,可以是一个FIFO队列,通常使用Redis Dj ...