Solution -「Gym 102759G」LCS 8
\(\mathcal{Description}\)
Link.
给定 \(m\),和长度为 \(n\),字符集为大写字母的字符串 \(s\),求字符集相同且等长的字符串 \(t\) 的数量,使得 \(s,t\) 的 LCS 长度不小于 \(n-m\)。答案模 \((10^9+7)\)。
\(n\le5\times10^4\),\(m\le3\)。
\(\mathcal{Solution}\)
有个傻瓜怕不是忘了 DP of DP 这种东西。
LCS 的 DP 信息是很方便压缩储存的,在决策 \(t_{i+1}\) 时,我们希望知道 \(g_{i,\max\{0,i-m\}..\min\{n,i+m\}}\)(\(g_{i,j}\) 即 \(s[:i]\) 和 \(t[:j]\) 的 LCS),记录第一个位置和其对应下标的差值(不超过 \(m\))以及后面位置的差分(\(01\) 状态),可以得到一个 \((m+1)2^{2m}\) 的压缩,转移枚举在这 \(\mathcal O(m)\) 个内的字符,整体转移不在的字符,最劣复杂度为 \(\mathcal O(nm^22^{2m})\),不过明显跑不满。
\(\mathcal{Code}\)
写得很丑就试了 qwq。
/*~Rainybunny~*/
#include <cstdio>
#include <cassert>
#include <cstring>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
const int MAXN = 5e4, MAXM = 3, MOD = 1e9 + 7;
int n, m, f[2][MAXM + 1][1 << 2 * MAXM];
char str[MAXN + 5];
/*
f(i,i-m), f(i,j-m+1), ..., f(i,i+m)
x , +[0] , +[...], +[2m-1]
*/
inline int imin( const int a, const int b ) { return a < b ? a : b; }
inline int imax( const int a, const int b ) { return a < b ? b : a; }
inline int mul( const int a, const int b ) { return int( 1ll * a * b % MOD ); }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
int main() {
scanf( "%s %d", str + 1, &m ), n = int( strlen( str + 1 ) );
str[0] = -1; rep ( i, 1, n ) str[i] -= 'A';
f[0][0][0] = 1;
for ( int i = 0, sta = 0; i < n; ++i, sta ^= 1 ) {
rep ( j, 0, m ) rep ( S, 0, ( 1 << 2 * m ) - 1 ) {
int& cur = f[sta][j][S];
if ( !cur ) continue;
// printf( "f(%d,%d,%d)=%d\n", i, j, S, cur );
static bool vis[26] = {}; int cnt = 0;
int tp = imax( i - m, 0 ), sp = imax( i - m + 1, 0 ), u, v;
rep ( t, sp, imin( i + m + 1, n ) ) if ( t && !vis[str[t]] ) {
int c = str[t]; vis[c] = true, ++cnt;
int las[2] = { imax( i - m, 0 ) - j, 0 }, fir = 0, T = 0;
// f(i,j)=max{f(i-1,j),f(i,j-1),f(i-1,j-1)+1}.
rep ( k, sp, imin( i + m + 1, n ) ) {
u = las[0] + ( S >> ( k - tp - 1 ) & 1 );
v = imax( imax( las[1], u ), las[0] + ( str[k] == c ) );
if ( k == sp ) {
fir = k - v;
if ( fir > m ) break;
} else T |= ( v > las[1] ) << ( k - sp - 1 );
las[0] = u, las[1] = v;
}
if ( fir <= m ) addeq( f[!sta][fir][T], cur );
}
{
int las[2] = { imax( i - m, 0 ) - j, 0 }, fir = 0, T = 0;
rep ( k, sp, imin( i + m + 1, n ) ) {
u = las[0] + ( S >> ( k - tp - 1 ) & 1 );
v = imax( las[1], u );
if ( k == sp ) {
fir = k - v;
if ( fir > m ) break;
} else T |= ( v > las[1] ) << ( k - sp - 1 );
las[0] = u, las[1] = v;
}
if ( fir <= m ) addeq( f[!sta][fir][T], mul( cur, 26 - cnt ) );
}
rep ( t, sp, imin( i + m + 1, n ) ) if ( t ) vis[str[t]] = false;
cur = 0;
}
}
int ans = 0;
rep ( i, 0, m ) rep ( S, 0, ( 1 << 2 * m ) - 1 ) {
// if ( f[n & 1][i][S] )
// printf( "f(%d,%d,%d)=%d\n", n, i, S, f[n & 1][i][S] );
assert( !f[n & 1][i][S] || !( S >> m ) );
if ( imax( n - m, 0 ) - i + __builtin_popcount( S ) >= n - m ) {
addeq( ans, f[n & 1][i][S] );
}
}
printf( "%d\n", ans );
return 0;
}
Solution -「Gym 102759G」LCS 8的更多相关文章
- Solution -「Gym 102979E」Expected Distance
\(\mathcal{Description}\) Link. 用给定的 \(\{a_{n-1}\},\{c_n\}\) 生成一棵含有 \(n\) 个点的树,其中 \(u\) 连向 \([1, ...
- Solution -「Gym 102979L」 Lights On The Road
\(\mathcal{Description}\) Link. 给定序列 \(\{w_n\}\),选择 \(i\) 位置的代价为 \(w_i\),要求每个位置要不被选择,要不左右两个位置至少被 ...
- Solution -「Gym 102956F」Find the XOR
\(\mathcal{Description}\) Link. 给定 \(n\) 个点 \(m\) 条边的连通无向图 \(G\),边有边权.其中 \(u,v\) 的距离 \(d(u,v)\) ...
- Solution -「Gym 102956B」Beautiful Sequence Unraveling
\(\mathcal{Description}\) Link. 求长度为 \(n\),值域为 \([1,m]\) 的整数序列 \(\lang a_n\rang\) 的个数,满足 \(\not\ ...
- Solution -「Gym 102956F」Border Similarity Undertaking
\(\mathcal{Description}\) Link. 给定一张 \(n\times m\) 的表格,每个格子上写有一个小写字母.求其中长宽至少为 \(2\),且边界格子上字母相同的矩 ...
- Solution -「Gym 102956A」Belarusian State University
\(\mathcal{Description}\) Link. 给定两个不超过 \(2^n-1\) 次的多项式 \(A,B\),对于第 \(i\in[0,n)\) 个二进制位,定义任意一个二元 ...
- Solution -「Gym 102798I」Sean the Cuber
\(\mathcal{Description}\) Link. 给定两个可还原的二阶魔方,求从其中一个状态拧到另一个状态的最小步数. 数据组数 \(T\le2.5\times10^5\). ...
- Solution -「Gym 102798K」Tree Tweaking
\(\mathcal{Description}\) Link. 给定排列 \(\{p_n\}\),求任意重排 \(p_{l..r}\) 的元素后,将 \(\{p_n\}\) 依次插入二叉搜索树 ...
- Solution -「Gym 102798E」So Many Possibilities...
\(\mathcal{Description}\) Link. 给定非负整数序列 \(\{a_n\}\) 和 \(m\),每次随机在 \(\{a\}\) 中取一个非零的 \(a_i\)(保证存 ...
随机推荐
- scrollTop、scrollHeight与clientHeight
MDN上概念 scrollTop:获取或设置一个元素的内容垂直滚动的像素数. scrollHeight:一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容. clientHeight:元素内部 ...
- day 18 C语言顺序结构基础定义1
(1).有以下程序: 程序运行后的输出结果是[B] (A).3,5,5,3 (B).3,5,3,5 (C).5,3,3,5 (D).5,3,5,3 这个题其实也可以弄成改错题,传到函数里面要对其值操作 ...
- java计算器(简单版)
前言 之前在学习完Java的方法后,我发现自己可以开始写计算器这个"经典"的项目了,于是我花了一点时间写下了这个计算器的程序,也写下了这篇文章. 在这里,我需要说明一下,这个程序只 ...
- Electron+Vue开发跨平台桌面应用
Electron+Vue开发跨平台桌面应用 xiangzhihong发布于 2019-12-23 虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求.受限于浏览器的沙盒限制,网页应用无法满足某 ...
- leetcode刷题目录
leetcode刷题目录 1. 两数之和 2. 两数相加 3. 无重复字符的最长子串 4. 寻找两个有序数组的中位数 5. 最长回文子串 6. Z 字形变换 7. 整数反转 8. 字符串转换整数 (a ...
- C# 获取DPI例子
public static float GetDpiX() { System.Windows.Forms.Panel p = new System.Windows.Forms.Panel(); Sys ...
- 【解决了一个小问题】golang中引用一个路径较长的库,导致goland中出现"module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2"
在项目中的go.mod文件中有这样一句: require ( github.com/xxx-devops/xx1/sdk/go v2.2.3 ) 项目的编译没有问题,但是goland中出现如下提示: ...
- MySQL的MyISAM与InnoDB的索引方式
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 MyISAM引擎使用B+Tr ...
- 给自己的网站装上SSL证书
给网站装上SSL证书 前言 主要是因为自己的阿里云快过期了,自己的博客也重新用了一下Halo,重新安装SSL的时候有些地方忘了,所以在此留个记录! 关于SSL 阮一峰<图解图解SSL/TLS协议 ...
- WebGPU图形编程(1):建立开发环境 <学习引自徐博士教程>
首先感谢徐博士提供的视频教程,我的博客记录也是学习徐博士进行的自我总结,老徐B站学习视频链接网址:WebGPU图形编程 - 免费视频教程(1):建立开发环境_哔哩哔哩_bilibili 创建之前你需要 ...