首页 > 其他分享 >[AGC024F] Simple Subsequence Problem

[AGC024F] Simple Subsequence Problem

时间:2023-07-26 12:11:06浏览次数:36  
标签:int string Simple AGC024F leq Subsequence ls th dp

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;					
		}
	}
}

标签:int,string,Simple,AGC024F,leq,Subsequence,ls,th,dp
From: https://www.cnblogs.com/mekoszc/p/17582150.html

相关文章

  • [ARC150F] Constant Sum Subsequence
    ProblemStatementWehaveasequenceofpositiveintegersoflength$N^2$,$A=(A_1,\A_2,\\dots,\A_{N^2})$,andapositiveinteger$S$.Forthissequenceofpositiveintegers,$A_i=A_{i+N}$holdsforpositiveintegers$i\(1\leqi\leqN^2-N)$,an......
  • POJ 1458 Common Subsequence(动态规划)
    传送门代码如下:#include<iostream>#include<cstdio>usingnamespacestd;intmaxLen[1000][1000];intmain(){strings1,s2;while(cin>>s1>>s2){intlength1=s1.length();intlength2=s2.length();......
  • CTFer成长记录——CTF之Web专题·bugku-Simple_SSTI_2
    一、题目链接https://ctf.bugku.com/challenges/detail/id/203.html二、解法步骤  题目是SSTI,也就是服务器模板注入,页面提示我们需要传递一个flag参数。  由于是模板,可以传flag={{config}}看看:显示说明这里存在命令执行的漏洞,查询资料发现此处可以执......
  • Subsequence Addition
    #SubsequenceAddition(HardVersion)##题面翻译本题为困难版,两题的唯一区别在于数据范围的大小。数列$a$最开始只有一个数$1$,你可以进行若干次操作,每次操作你可以选取$k$个数($k$无限制,小于等于$a$的大小即可),将这$k$个数的和放入$a$的任意一个位置。给定一个长......
  • CF1132G Greedy Subsequences
    简单题。\(i\)向\(i\)后第一个\(j\),\(a_j\)比\(a_i\)大的点连边,不难发现最后形成了一棵森林,并且一个点的父亲\(\text{fa}_i>i\)。题目变成了取\([l,r]\)中的点为起点,向祖先方向走去并且终点编号\(\ler\)的最长链长度。考虑离线,维护从每个点开始的最长链长度\(f_i......
  • [LeetCode] 2486. Append Characters to String to Make Subsequence
    Youaregiventwostrings s and t consistingofonlylowercaseEnglishletters.Return theminimumnumberofcharactersthatneedtobeappendedtotheendof s sothat t becomesa subsequence of s.A subsequence isastringthatcanbederived......
  • hdu 2227 Find the nondecreasing subsequences (树状数组+dp+离散化)
    题意:给定一个长度为n(n<=100000)的整数序列,求其中的递增序列的个数。对于某些序列中的递增序列的个数是可以用dp来求解的,其状态转移方程为:dp[i]=sum(dp[j])+1,j<i&&a[j]<a[i]根据状态转移方程可以得知这样dp的时间复杂度为O(n^2),而对于题目给定的10^6的数量级来说,这样......
  • 博客园主题 - SimpleMemory
    博客园主题-SimpleMemoryGitHub地址:https://github.com/BNDong/Cnblogs-Theme-SimpleMemory官方文档地址:https://bndong.github.io/Cnblogs-Theme-SimpleMemory/v2/#/页面效果:https://www.cnblogs.com/bndong/安装使用定制化设置博客侧边栏公告<scripttype="text/java......
  • [HUBUCTF 2022 新生赛]simple_RE
    [HUBUCTF2022新生赛]simple_RE查壳,64位找main函数,F5查看伪代码,简单分析一下int__cdeclmain(intargc,constchar**argv,constchar**envp){intv4;//[rsp+24h][rbp-44h]BYREFvoid*Buf1;//[rsp+28h][rbp-40h]BYREFcharv6[56];//[rsp+30h][rbp......
  • python中tk的simpledialog.askstring报错解决方案
    simpledialog.askstring还是比较好用的,能够很方便的获取用户输入的文本,但是在多线程中会出现下面的错误:_tkinter.TclError:window".!_querystring"wasdeletedbeforeitsvisibilitychanged解决的方案参考:https://stackoverflow.com/questions/53480400/tkinter-ask......