[AGC024F] Simple Subsequence Problem
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
1if 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
0and1. - $1 \leq K \leq |S|$
- $K$ is an integer.
神奇 dp。
记的时候如何区分 1 和 01?统一在前面
考虑暴力怎么做。枚举一个子串,然后数有多少个子串包含这个子串。复杂度 \(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的更多相关文章
- @atcoder - AGC024F@ Simple Subsequence Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定由若干长度 <= N 的 01 字符串组成的集合 S. ...
- [题解] [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 ...
随机推荐
- [ABC150E] Change a Little Bit
2023-03-10 题目 题目传送门 翻译 翻译 难度&重要性(1~10):7 题目来源 AtCoder 题目算法 数学,贪心 解题思路 显然 \(C_i\) 越小的位越早被修改越好.所以我 ...
- 番外1.ssh连接管理器
目录 本篇前瞻 项目背景 ssh连接管理器 优点 使用方式 配置 使用方法 快速开始 注意点 使用样例 本篇后记 本篇前瞻 学习完go语言基础的专栏,我们究竟写出怎么样的实用工具呢?我在github上 ...
- 《SQL与数据库基础》02. SQL-DDL
目录 DDL 库管理 表管理 本文以 MySQL 为例 DDL 库管理 查看有哪些数据库: SHOW DATABASES; 使用某个数据库: USE 数据库名; 查看当前使用的数据库: SELECT ...
- 《CTFshow-Web入门》03. Web 21~30
@ 目录 web21 题解 原理 web22 题解 原理 web23 题解 原理 web24 题解 原理 web25 题解 原理 web26 题解 web27 题解 web28 题解 web29 题解 ...
- 多层前馈神经网络及BP算法
一.多层前馈神经网络 首先说下多层前馈神经网络,BP算法,BP神经网络之间的关系.多层前馈[multilayer feed-forward]神经网络由一个输入层.一个或多个隐藏层和一个输出层组成,后向 ...
- 关于XXLJOB集群模式下调度失败的问题
xxljob在集群模式下调度高频任务时,有时会出现调度失败的问题,具体报错如下: java.io.EOFException: HttpConnectionOverHTTP@6be8bf0c(l:/10 ...
- 4.go语言复合类型简述
目录 1. 本章前瞻 2.来自leetcode的例题 描述 分析 题解 3. 复合类型新版本的变化 3.1 string和[]byte的高效转化 3.2 内置函数clear 4. 复合类型概述 4.1 ...
- oracle导入导出某个schema数据
背景 公司之前部门拆分,但一些服务并没有拆分清楚.其中一个老服务,两个部门都在用,现在为了避免互相影响,决定克隆该服务.克隆就要克隆全套,当然也包括数据库,我们这个老服务,用的oracle,所以,就涉 ...
- Python比较字符串格式类型时间大小
已知的格式是 06/24/2021 15:47:01.491 时间比较的思路是,把数据转换成时间戳比较: 第一步是把 06/24/2021 15:47:01.491 格式转换称 2021-06-24 ...
- 如何使用Java创建数据透视表并导出为PDF
摘要:本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 数据透视分析是一种强大的工具,可以帮助我们从大量数据中提取有用信 ...