题目

\(n \le 10^{18} \ , \ |T| \le 10^5\)

题解

  • 显然,最少的操作次数一定是贪心地能匹配就匹配

  • 我们可以建出\(T\)的SAM,把SAM不能走的边补到根的后继节点

  • 问题变成在SAM上设计一条长度为\(n\)的路径使得它绕回根的次数最多

  • 由于字符集为4,并且我们只关心绕回根的次数

  • 可以在SAM上dp预处理一个\(4 \times 4\)的矩阵表示从\(x\)开头经过根到\(y\)开头的最小长度

  • 二分答案,矩阵快速幂check

  • 考场没有想到二分,直接搜索了一下ABCD的顺序然后重复走中间的环,水过去了。。

    #include<bits/stdc++.h>
    #define ll long long
    #define inf 1e9 using namespace std; const int N=200010;
    int l,cnt,ch[N][4],fa[N],len[N],d[N],a[10],used[N];
    char s[N];
    ll n,ans=1,f[N],dis[4][4]; void chkmn(ll&x,ll y){if(x>y)x=y;}
    void chkmx(ll&x,ll y){if(x<y)x=y;} void pre_dfs(int u){
    if(used[u])return;
    used[u]=1;
    for(int i=0;i<4;++i){
    int v=ch[u][i];
    if(!v)continue;
    d[v]++;
    pre_dfs(v);
    }
    } void get_dis(int I){
    static queue<int>q;
    q.push(ch[1][I]);
    f[ch[1][I]]=1;
    while(!q.empty()){
    int u=q.front();q.pop();
    for(int i=0;i<4;++i){
    int v=ch[u][i];
    if(!v){chkmn(dis[I][i],f[u]);continue;}
    chkmn(f[v],f[u]+1);
    if(!--d[v])q.push(v);
    }
    }
    } void get_ans(int m){
    static int vis[4],s1,s2,s3,st[10],tp;
    for(int i=s1=s2=s3=0;i<4;++i)vis[i]=0;
    vis[st[tp=1]=a[0]]=1;
    for(int i=1;i<m;++i){
    s1+=dis[a[i-1]][a[i]];
    if(vis[a[i]]){
    int lst=a[i];
    while(1){
    s2+=dis[st[tp]][lst];s3++;
    if(st[tp]==a[i])break;
    vis[st[tp]]=0;
    lst=st[tp--];
    }
    continue;
    }
    vis[st[++tp]=a[i]]=1;
    }
    if(n<=s1)return;
    chkmx(ans, m);
    if(s2)chkmx(ans, m+1ll*(n-1-s1)/s2*s3);
    } void dfs(int x){
    if(x>8)return;
    if(x>1)get_ans(x);
    for(int i=0;i<4;++i){
    a[x]=i;
    dfs(x+1);
    }
    } int main(){
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    scanf("%lld%s",&n,s);l=strlen(s);
    cnt=1;
    for(int i=0,lst=1;i<l;++i){
    int x=s[i]-'A',p=lst,np=++cnt;
    len[lst=np]=len[p]+1;
    while(p&&!ch[p][x])ch[p][x]=np,p=fa[p];
    if(!p){fa[np]=1;continue;}
    int q=ch[p][x];
    if(len[q]==len[p]+1)fa[np]=q;
    else{
    int nq=++cnt;
    len[nq]=len[p]+1;
    memcpy(ch[nq],ch[q],sizeof(ch[q]));
    fa[nq]=fa[q];fa[np]=fa[q]=nq;
    while(p&&ch[p][x]==q)ch[p][x]=nq,p=fa[p];
    }
    } for(int i=0;i<4;++i)if(!ch[1][i]){return cout<<n<<endl,0;}
    memset(dis,0x3f,sizeof(dis));
    memset(f,0x3f,sizeof(f)); for(int i=0;i<4;++i){
    for(int j=1;j<=cnt;++j)d[j]=used[j]=0;
    pre_dfs(ch[1][i]);
    get_dis(i);
    } dfs(0); cout<<ans<<endl; return 0;
    }

【JZOJ6213】【20190613】String的更多相关文章

  1. 【重走Android之路】【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder

    [重走Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder   1.String String是Java中的一个final ...

  2. Android NDK 【错误】The method loadLibrary(String) is undefined for the type Settings.Syste

    [错误]The method loadLibrary(String) is undefined for the type Settings.System [解决方法] 不要加入包import andr ...

  3. 【动态规划】【最短路】Codeforces 710E Generate a String

    题目链接: http://codeforces.com/problemset/problem/710/E 题目大意: 问写N个字符的最小花费,写一个字符或者删除一个字符花费A,将当前的字符数量翻倍花费 ...

  4. 【手记】小心在where中使用NEWID()的大坑 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题 【C#】组件分享:FormDragger窗体拖拽器 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed

    [手记]小心在where中使用NEWID()的大坑 这个表达式: ABS(CHECKSUM(NEWID())) % 3 --把GUID弄成正整数,然后取模 是随机返回0.1.2这三个数,不可能返回其它 ...

  5. 【C++探索之旅】第二部分第一课:面向对象初探,string的惊天内幕

    内容简单介绍 1.第二部分第一课:面向对象初探.string的惊天内幕 2.第二部分第二课预告:掀起了"类"的盖头来(一) 面向对象初探,string的惊天内幕 上一课<[C ...

  6. 【LeetCode】678. Valid Parenthesis String 解题报告(Python)

    [LeetCode]678. Valid Parenthesis String 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人 ...

  7. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  8. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  9. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  10. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

随机推荐

  1. 在Eclipse中使用Beyond Compare做为比较工具

    1.下载org.eclipse.externaltools-Update-0.8.9.v201003051612.zip插件包 接下来,要下载Beyond Compare的插件,http://beyo ...

  2. Micro 设计文档

    1.顶部 即时通讯 | 应用软件 | 网络学院 | 帮助中心 | 开发者中心 | 控制台 2.导航 首页 免费制作 免费下载 功能介绍 示例演示 云数据 支持与服务 免费制作:https://www. ...

  3. CMS-headless or non-headless, page-based or object-based storage?

    内容管理系统对于很多在线教育企业来说都是至关重要的,他不仅可以用于内容的创作,编辑,发布,撤销,展示也可以用于运营或者市场产生他们需要的页面. 传统上,Wordpress是一个非常成功的CMS,他将内 ...

  4. Docker Cheatsheet

    一.创建 docker create:创建容器,处于停止状态. centos:latest:centos容器:最新版本(也可以指定具体的版本号).本地有就使用本地镜像,没有则从远程镜像库拉取.创建成功 ...

  5. ubuntu ufw相关命令

    引自:http://www.cnblogs.com/jiangyao/archive/2010/05/19/1738909.html 就这句话就够了,下面的可以不看 sudo  ufw enable| ...

  6. 2019 头条java面试笔试总结 (含面试题解析)

       本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条等公司offer,岗位是Java后端开发,因为发展原因最终选择去了头条,入职一年时间了,也成为了面试官,之前面 ...

  7. logback配置和使用

    简介 logback是由log4j创始人设计的又一个开源日志组件.当前分成三个模块: logback-core是其它两个模块的基础模块. logback-classic是log4j的一个 改良版本.此 ...

  8. 【按键精灵篇】如何做一个自动打开APP进入注册页面自动输入自己手机号

    按键精灵,虽然很早听过,但是一直没有真正使用过,所以最近有点时间也简单试一下,通过脚本自动清理APP缓存,打开百家号并自动进入注册页面输入自己的手机号. 软件清单 1. 雷电手机模拟器:https:/ ...

  9. C#8.0—非空引用类型

    非空引用类型--C#8.0 原文地址:https://devblogs.microsoft.com/dotnet/try-out-nullable-reference-types/?utm_sourc ...

  10. Android Ant Build 遇到的问题

    Ant的具体使用这里就不详细说明了,这里记录下自己使用Ant批量打包apk的时候遇到的问题. 1. build 出现 crunch等字样的错误 <span style="color: ...