description

CodeForces

定义一个正整数\(x\)是合适的当且仅当\(l\le x\le r\),其中\(l,r\le 10^{800}\)。

找到一个长度为\(n\)的数字串,使其包含合适的数作为子串的次数最多,\(n\le 2000\)。

如果有多解,输出字典序最小的那个。

solution

如果模式串的个数不多,那么直接套用AC自动机上数位dp的方法即可。

关于这一方法可参见[SDOI2014]数数

现在这个做法的缺陷是要放入的串太多。

考虑简化。

根据数位dp的思想,一个固定位数的数只要达到安全态,后面的数码可以随意选择,

因此我们将\(\ge l\)或\(\le r\)的达到安全态的前缀都放入\(AC\)自动机;

设计\(dp\)状态为\(f[i][u]\),表示考虑了前\(i\)位,目前匹配到\(AC\)自动机的节点\(u\)时,已经能够匹配的子串个数。

对于后面的随意数码,由于题目限制长度为\(n\),所以只需要判断其长度是否\(>n-i-1\)即可。

code

实现代码长度居然达到\(3.5k\)...

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define FL "a"
using namespace std;
typedef long long ll;
typedef long double dd;
const int N=2e3+10;
const int M=2e4+10;
const int inf=2147483647;
const dd pi=acos(-1);
const ll INF=1ll<<60;
inline ll read(){
ll data=0,w=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
inline void file(){
freopen(FL".in","r",stdin);
freopen(FL".out","w",stdout);
} char sl[N],sr[N];
int n,lenl,lenr,cnt,vis[M][10],fail[M],g[M][N],f[N][M];
inline void upd(int &a,int b){a=a>b?a:b;}
inline void getpre(){
scanf("%s",sl+1);lenl=strlen(sl+1);
scanf("%s",sr+1);lenr=strlen(sr+1);
n=read();
if(lenl==lenr){
int ul,ur;ul=ur=0;
for(int i=1;i<=lenl;i++)
if(ul==ur){
for(int c=sl[i]-48+1;c<sr[i]-48;c++){
if(!vis[ul][c])vis[ul][c]=++cnt;
g[vis[ul][c]][lenl-i]++;
}
if(!vis[ul][sl[i]-48])vis[ul][sl[i]-48]=++cnt;
if(!vis[ur][sr[i]-48])vis[ur][sr[i]-48]=++cnt;
ul=vis[ul][sl[i]-48];ur=vis[ur][sr[i]-48];
}
else{
for(int c=sl[i]-48+1;c<10;c++){
if(!vis[ul][c])vis[ul][c]=++cnt;
g[vis[ul][c]][lenl-i]++;
}
for(int c=0;c<sr[i]-48;c++){
if(!vis[ur][c])vis[ur][c]=++cnt;
g[vis[ur][c]][lenr-i]++;
}
if(!vis[ul][sl[i]-48])vis[ul][sl[i]-48]=++cnt;
if(!vis[ur][sr[i]-48])vis[ur][sr[i]-48]=++cnt;
ul=vis[ul][sl[i]-48];ur=vis[ur][sr[i]-48];
}
g[ul][0]++;if(ul!=ur)g[ur][0]++;
}
else{
int u;u=0;
for(int i=1;i<=lenl;i++){
for(int c=sl[i]-48+1;c<10;c++){
if(!vis[u][c])vis[u][c]=++cnt;
g[vis[u][c]][lenl-i]++;
}
if(!vis[u][sl[i]-48])vis[u][sl[i]-48]=++cnt;
u=vis[u][sl[i]-48];
}
g[u][0]++;u=0;
for(int i=1;i<=lenr;i++){
for(int c=0;c<sr[i]-48;c++){
if(!vis[u][c])vis[u][c]=++cnt;
g[vis[u][c]][lenr-i]++;
}
if(!vis[u][sr[i]-48])vis[u][sr[i]-48]=++cnt;
u=vis[u][sr[i]-48];
}
g[u][0]++;
for(int i=lenl+1;i<lenr;i++)
for(int c=1;c<10;c++){
if(!vis[0][c])vis[0][c]=++cnt;
g[vis[0][c]][i-1]++;
}
}
for(int i=0;i<=cnt;i++)vis[0][0]=0;
} inline void getfail(){
static queue<int>Q;while(!Q.empty())Q.pop();
for(int c=0;c<10;c++)if(vis[0][c])Q.push(vis[0][c]);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int c=0;c<10;c++){
int &v=vis[u][c];
if(v){
Q.push(v);fail[v]=vis[fail[u]][c];
for(int i=0;i<=n;i++)g[v][i]+=g[fail[v]][i];
}
else v=vis[fail[u]][c];
}
}
for(int u=0;u<=cnt;u++)
for(int i=0;i<=n;i++)
g[u][i]+=g[u][i-1];
}
inline void init(){
getpre();
getfail();
} bool could[N][M];
inline void solve(){
memset(f,128,sizeof(f));f[0][0]=0;
for(int i=0;i<=n;i++)
for(int u=0;u<=cnt;u++)
if(f[i][u]>=0){
f[i][u]+=g[u][n-i];
for(int c=0;c<10;c++)
upd(f[i+1][vis[u][c]],f[i][u]);
}
int ans=0;
for(int u=0;u<=cnt;u++)upd(ans,f[n][u]);
printf("%d\n",ans);
for(int u=0;u<=cnt;u++)if(f[n][u]==ans)could[n][u]=1;
for(int i=n-1;~i;i--)
for(int u=0;u<=cnt;u++)
if(f[i][u]>=0)
for(int c=0;c<10;c++)
if(could[i+1][vis[u][c]]&&
f[i+1][vis[u][c]]==f[i][u]+g[vis[u][c]][n-i-1]){
could[i][u]=1;break;
}
assert(could[0][0]==1);
int u=0;
for(int i=0;i<n;i++)
for(int c=0;c<10;c++)
if(could[i+1][vis[u][c]]&&f[i+1][vis[u][c]]==f[i][u]+g[vis[u][c]][n-i-1]){
putchar(48+c);u=vis[u][c];break;
}
} int main()
{
init();
solve();
return 0;
}

[CF1110H]Modest Substrings的更多相关文章

  1. CF1110H Modest Substrings AC自动机、DP

    传送门 如果\(r-l\)比较小,可以将所有满足条件的串扔进\(AC\)自动机然后在上面DP,从前往后确定字符串的每一位. 但是\(l,r \leq 10^{800}\)就十分不可行,所以需要优化这个 ...

  2. CodeForces 1110H. Modest Substrings

    题目简述:给定$1 \leq l \leq r \leq 10^{800}$,求一个长度为$n \leq 2000$的数字串$s$,其含有最多的[好]子串.一个串$s$是[好]的,如果将其看做数字时无 ...

  3. CodeForces Global Round 1

    CodeForces Global Round 1 CF新的比赛呢(虽然没啥区别)!这种报名的人多的比赛涨分是真的快.... 所以就写下题解吧. A. Parity 太简单了,随便模拟一下就完了. B ...

  4. [LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  5. Leetcode: Unique Substrings in Wraparound String

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  6. CSU-1632 Repeated Substrings (后缀数组)

    Description String analysis often arises in applications from biology and chemistry, such as the stu ...

  7. CF451D Count Good Substrings (DP)

    Codeforces Round #258 (Div. 2) Count Good Substrings D. Count Good Substrings time limit per test 2 ...

  8. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

  9. 后缀数组---New Distinct Substrings

    Description Given a string, we need to find the total number of its distinct substrings. Input T- nu ...

随机推荐

  1. opengl矩阵向量

    如何创建一个物体.着色.加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,仍是不够有趣.我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理 ...

  2. Centos7下使用RDO方式安装openstack-r版

    一.前言 OpenStack是一个开源的云计算管理平台项目,OpenStack支持几乎所有类型的云环境,项目目标是提供实施简单.可大规模扩展.丰富.标准统一的云计算管理平台.OpenStack通过各种 ...

  3. Codeforces1151E,F | 553Div2 | 瞎讲报告

    传送链接 E. Number of Components 当时思博了..一直在想对于\([1,r]\)的联通块和\([1,l-1]\)的联通块推到\([l,r]\)的联通块...我真的是傻了..这题明 ...

  4. Linux虚拟机安装教程

    必备组件: vmware(程序主题) 链接:https://pan.baidu.com/s/14OplOGOQTVAnf0iDqgDhDQ 提取码:jape centos(Linux系统) 链接:ht ...

  5. 基于Neutron的Kubernetes SDN实践经验之谈

    首先,向大家科普下Kubernetes所选择的CNI网络接口,简单介绍下网络实现的背景. CNI即Container Network Interface,是一套容器网络的定义规范,包括方法规范.参数规 ...

  6. 简单安装与使用虚拟环境virtualenv

    安装虚拟环境的命令如下: sudo pip install virtualenv sudo pip install virtualenvwrapper 创建虚拟环境的命令如下: mkvirtualen ...

  7. Cocoapods更改安装版本及卸载、ruby版本检测和安装

    修改于:2017.1.10 我们实际过程中会遇到很多的问题,并且各式各样,特别是各种系统.工具版本升级后遇到的问题,最后的杀手锏就是彻底删干净,重装. 一. 移除pod组件 这条指令会告诉你Cocoa ...

  8. 导出excel失败,提示提示加载类型库/DDL出错

    首先,这里提供的解决办法仅适用于出现如下异常的情况:无法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“M ...

  9. 【数据预处理】TIMIT语料库WAV文件转换

    1 问题描述 这两天复现代码.先构造数据集,纯净语音.不同噪声.不同SNR的混合语音.其中纯净语音由两部分组成,IEEE corpus和TIMIT. 一开始我用MATLAB中的audioread读取音 ...

  10. 软工大作业DB天气项目风险评估

    风险 发生概率 损失 风险度 解决方案 项目延期 80% 浪费时间,项目完成进度降低,考试得分低 79% 提前做好详细的准备工作,各方面做好沟通. 工作效率低下 30% 影响进度,使项目延期. 85% ...