Problem Statement

You are given a set $S$ of strings consisting of 0 and 1, and an integer $K$.

Find the longest string that is a subsequence of $K$ or more different strings in $S$.
If there are multiple strings that satisfy this condition, find the lexicographically smallest such string.

Here, $S$ is given in the format below:

  • The data directly given to you is an integer $N$, and $N+1$ strings $X_0,X_1,...,X_N$. For every $i$ $(0\leq i\leq N)$, the length of $X_i$ is $2^i$.
  • For every pair of two integers $(i,j)$ $(0\leq i\leq N,0\leq j\leq 2^i-1)$, the $j$-th character of $X_i$ is 1 if and only if the binary representation of $j$ with $i$ digits (possibly with leading zeros) belongs to $S$. Here, the first and last characters in $X_i$ are called the $0$-th and $(2^i-1)$-th characters, respectively.
  • $S$ does not contain a string with length $N+1$ or more.

Here, a string $A$ is a subsequence of another string $B$ when there exists a sequence of integers $t_1 < ... < t_{|A|}$ such that, for every $i$ $(1\leq i\leq |A|)$, the $i$-th character of $A$ and the $t_i$-th character of $B$ is equal.

Constraints

  • $0 \leq N \leq 20$
  • $X_i(0\leq i\leq N)$ is a string of length $2^i$ consisting of 0 and 1.
  • $1 \leq K \leq |S|$
  • $K$ is an integer.

神奇 dp。

记的时候如何区分 101?统一在前面

考虑暴力怎么做。枚举一个子串,然后数有多少个子串包含这个子串。复杂度 \(4^N\)。

怎么判断一个子串是否是另一个子串的子序列呢?子序列自动机。定义 \(nx_{i,j}\) 为第 \(i\) 位出现的下一个 \(j\) 在哪里,跑就行了。

思考在跑子序列自动机的时候有没有一些重复的状态,发现在某些状态下,已经匹配好的和需要匹配好的串总数是不多的。也就是说,定义 \(dp_{s,t}\) 为已经匹配好的串是 \(s\),等待匹配的串是 \(t\),有多少个大串能转化成这种样子。

发现 \(|S|+|T|\le n\),所以改 dp 定义为 \(dp_{s,i}\) 为串 \(s\),前 \(i\) 个字符为已经匹配好的,剩下的是等待匹配的。

#include<bits/stdc++.h>
using namespace std;
const int N=2.1e6;
int n,k,m,ln[N],ls[N][21][2],dp[21][N],lg[N],s,ans[N],ret;//dp[i][j]表示总串j,匹配了j位的答案,ls[i][j][k]表示数字i在第j位前的第一个k在第几位
char ch;
int main()
{
for(int i=2;i<N;i++)
lg[i]=lg[i>>1]+1;
scanf("%d%d",&n,&k);
for(int i=0;i<=n;i++)
{
for(int j=0;j<(1<<i);j++)
{
ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
if(ch^48)
dp[0][1<<i|j]++;
}
}
for(int i=1;i<(1<<n+1);i++)
{
m=lg[i],s=i-(1<<m);
ls[i][0][0]=ls[i][0][1]=-1;
for(int j=1;j<=m;j++)
ls[i][j][0]=ls[i][j-1][0],ls[i][j][1]=ls[i][j-1][1],ls[i][j][s>>(j-1)&1]=j-1;
}
// printf("%d %d\n",ls[6][3][0],ls[6][3][1]);
// printf("%d %d\n",ls[6][2][0],ls[6][2][1]);
// printf("%d %d\n",ls[6][1][0],ls[6][1][1]);
for(int i=0;i<=n;i++)//枚举长度
{
for(int j=(1<<i);j<(1<<n+1);j++)
{
m=lg[j];
int k=j>>(m-i);
ans[k]+=dp[i][j];
if(!dp[i][j])
continue;
if(i==m)
continue;
// printf("hjhyyds:%d %d %d\n",i,j,m);
int p=ls[j][m-i][0],q=ls[j][m-i][1];
// printf("%d %d %d %d %d\n",k,(k<<p+1)|(((1<<p+1)-1&j)),(k<<q+1)|((1<<q+1)-1&j),p,q);
if(~p)
dp[i+1][(k<<p+1)|(((1<<p+1)-1&j))]+=dp[i][j];
if(~q)
dp[i+1][(k<<q+1)|((1<<q+1)-1&j)]+=dp[i][j];
}
}
for(int i=1;i<(1<<n+1);i++)
if(ans[i]>=k)
ret=max(ret,lg[i]);
for(int i=1;i<(1<<n+1);i++)
{
if(ans[i]>=k&&lg[i]==ret)
{
for(int j=lg[i]-1;j>=0;j--)
putchar((i>>j&1)+48);
return 0;
}
}
}

[AGC024F] Simple Subsequence Problem的更多相关文章

  1. @atcoder - AGC024F@ Simple Subsequence Problem

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定由若干长度 <= N 的 01 字符串组成的集合 S. ...

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

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

  3. BZOJ 3489: A simple rmq problem

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

  4. ZOJ 3686 A Simple Tree Problem

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 通过实战操作学git

    虽然说 "好记性不如烂笔头",但是学习不看等于没学,学习不用等于不会,所以说"实战才是检验真理的唯一标准",通过实战则会学到很多东西. 因为陈** 太懒,并且不 ...

  2. Vue【原创】时间轴 【time-axis】&【date-axis】

    封装了关于时间轴的组件,有时候统计页面会用到. 效果图: 时间轴分为2种,一种是time-axis:范围选择模式,一种是date-axis:步长选择模式. 代码中涉及到的工具类和图片资源,请移步页面底 ...

  3. Xshell7 / Xftp7 永久免费,官网直连下载地址

    主要目的是让大家随时随地从官网下载Xshell和Xftp免费版(个人/家庭/学校免费) 最新变动:官方目前仅提供最新版以及上一个版本的软件下载!其他版本不提供下载 免费版5版本(最后一个版本,无任何限 ...

  4. pygame 入门实例教程 1 - 复古方块赛车游戏

    作者自我介绍:大爽歌, b站小UP主 ,直播编程+红警三 ,python1对1辅导老师 . 本教程步骤明确,过程清晰简明,最终代码量250行上下,适合学习pygame的新手. 项目代码已上传到我的gi ...

  5. 代码检视的新姿势!在IDEA中得到沉浸式Code Review新体验

    大家好,好久不见,又见面了. 在消失的这段时间里,我做了件大事,见证了儿子的出生并陪伴其一天天的成长.停止更文的200多天里,还能得到小伙伴们持续的支持,让我备受鼓励.对一个技术人员而言,分享技术观点 ...

  6. 前端远程调试方案 Chii 的使用经验分享

    前端远程调试方案 Chii 的使用经验分享 Chii 是与 weinre 一样的远程调试工具 ,主要是将 web inspector 替换为最新的 chrome devtools frontend 监 ...

  7. Matlab 设计仿真CIC滤波器

    2023.09.26 使用CIC滤波器用于降采样.同样的,CIC滤波器也适用于升采样. 参考连接: [1] Matlab中CIC滤波器的应用_dsp.cicdecimator_张海军2013的博客-C ...

  8. Solr Shiro Log4j2 命令执行--文件读取--反序列化--身份权限绕过--命令执行

    Solr Shiro Log4j2 命令执行--文件读取--反序列化--身份权限绕过--命令执行 solr 远程命令执行 (CVE-2019-17558) 漏洞简介 Apache Velocity是一 ...

  9. 【v2v迁移】Xen2kvm 迁移-linux篇

    迁移环境: 源平台:华为FusionComputeV100R006C10SPC101 目标平台:基于KVM虚拟化的云平台,本文以原生的libvirt为例 虚拟机:centos 7.6 具体操作步骤: ...

  10. 关于CAS等原子操作,说点别人没说的

    Java中提供了原子操作,可以简单看一下AtomicInteger类中的一个典型的原子操作incrementAndGet(),表示对原子整数变量进行加操作,并返回新的值.实现如下: public cl ...