首页 > 其他分享 >P8112 [Cnoi2021] 符文破译 题解

P8112 [Cnoi2021] 符文破译 题解

时间:2024-01-20 17:36:51浏览次数:21  
标签:匹配 int 题解 符文 P8112 字符串 长度

题目传送门

思路

先看数据范围,我们发现两个字符串的长度最大会达到 \(5 \times 10^7\)。 这立刻打消了我用暴力的想法。

于是,我选择了用 KMP 模式匹配,这一个能够在线性时间内判定字符串 \(A\) 是否是字符串 \(B\) 的字串,并求出字符串 \(A\) 在字符串 \(B\) 中各次出现的位置。

如果不清楚 KMP 算法是如何实现的,可以看看这个这个

我们知道一个字符串 \(A\) 每次往后成功匹配一次,匹配长度就会改变成一个不为 \(0\) 的数,而如果没有匹配成功,则会重新从头开始匹配,匹配长度为 \(0\)。

由此当匹配长度 \(j\) 为 \(0\) 时,无解输出 Fake

我们也知道每次匹配成功都是 \(A\left[i - j + 1 \sim i\right] = A\left[1 \sim j\right]\),所以当每次 \(i - j + 1\) 这一个起始点超过了上一次的终止点 \(i\) 时,就可以让划分的段数变小,更新答案。

代码

#include<bits/stdc++.h>
#define int long long
#define MAX 50000005
using namespace std;
int nxt[MAX],lens,lent,ans,tmp;
string s,t;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>lens>>lent>>s>>t;
    s=" "+s;
    t=" "+t;
    for(int i=2,j=0;i<=lens;i++){
        while(j&&s[i]!=s[j+1])j=nxt[j];
        if(s[i]==s[j+1])j++;
        nxt[i]=j;
    }
    for(int i=1,j=0;i<=lent;i++){
        while(j&&(j==lens||t[i]!=s[j+1]))j=nxt[j];
        if(t[i]==s[j+1])j++;
        if(j==0){
            cout<<"Fake\n";
            exit(0);
        }
        if(i-j+1>tmp){//更新答案
            ans++,tmp=i;
        }
    }
    cout<<ans<<'\n';
    return 0;
}

标签:匹配,int,题解,符文,P8112,字符串,长度
From: https://www.cnblogs.com/MithrilSwordXIV/p/17976794

相关文章

  • HDU2966 In case of failure 题解
    QuestionHDU2966Incaseoffailure给出平面上\(n\)个点坐标,求每个点最近的点的欧几里得距离的平方Solution算是一道K-D树的板子题维度\(K=2\)建立\(K-D\)树,在每一层更新当前最小答案\(now\_ans\),如果在然后继续遍历当前维度下距离\(\le\)的区块随机数据时间复......
  • 题解 P6226 [BalticOI 2019 Day1] 潜艇
    【洛谷博客】题解P6226[BalticOI2019Day1]潜艇题意很清楚,忽略。分析看到这种字符串题很容易想到直接广度优先搜索,复杂度\(O(rc4^m)\)。很显然承受不了,所以考虑DP。状态设计设\(f_{i,x,y}\)表示执行完前\(i\)个操作后位置\((x,y)\)能否作为终点。设命令字符......
  • 题解 [ABC321D] Set Menu
    【洛谷博客】题意给定一个长度为\(N\)的正整数数列\(A\),和一个长度为\(M\)的正整数数列\(B\),还有一个正整数\(P\)。你需要求:\[\sum\limits^{N}_{i=1}\sum\limits^{M}_{j=1}\min(A_i+B_j,P)\]分析说实话感觉这题比C还要简单。先考虑单个\(A_i\)能产生的贡献,可以......
  • 题解 [ABC321C] 321-like Searcher
    【洛谷博客】题意给定一个\(k\),你需要找到第\(k\)小的满足下面条件的正整数:对于这个数的每一位,高位大于低位。分析这个数据范围仅有一个\(1\lek\),让人很不好下手。我们不妨先做一个DP,看有多少个满足这样条件的数。设\(f_{i,j}\)表示有\(i\)位,且最高位为\(j\)......
  • 题解 [ABC242D] ABC Transform
    【洛谷博客】很巧妙的一道题。题意给定一个字符串\(S\),只包含字符A,B,C。每过一个时刻,字符会发生变化:A\(\to\)BC,B\(\to\)CA,C\(\to\)AB。设\(0\)时刻为\(S_0=S\)。进行\(Q\)次询问,每次询问时刻\(t\)时,字符串\(S_t\)中第\(k\)个字符。分析为了方便处理,我这里将所......
  • 题解 [ABC144E] Gluttony
    【洛谷博客】题意翻译很清楚,略。分析经过观察最优方案一定是消化代价小的配难消化的菜。所以将\(F\)从小到大排序,\(A\)从大到小排序,当然也可以反着来。因为有\(K\)次修行的机会,难以直接贪心。因为随着时间增加,修行的使用次数会减少,存在单调性。所以考虑使用二分答案转......
  • 题解 [ABC186F] Rook on Grid
    【洛谷博客】有一点难度,但不多。题意一个\(H\timesW\)的地图上有\(M\)个障碍物。有一辆车在\((1,1)\),一次行动可以向下或向右移动任意格(不得穿过障碍物)。求这辆车在最多两次行动中可能到达多少个格子。分析车有四种选择:向右、向下、先向右再向下、先向下再向右。然......
  • 题解 [ABC186E] Throne
    【洛谷博客】同余方程板子题,没过的可以先去看看。题意翻译给的很清楚。分析看到这个转圈圈的就很容易想到同余方程。为了方便处理,我们就将编号全部减\(1\),于是编号就变成\(0\simN-1\)。然后就可以很容易的列出同余方程:\[S+Kx\equiv0\pmod{N}\]移项可得:\[Kx\equ......
  • 题解 [ABC236D] Dance
    【洛谷博客】简单搜索题。题意将\(2N\)个人两两分组,每两个人配对会有一个快乐值,求快乐值异或最大。分析观察数据范围\(N\le8\),很容易想到搜索。又因为\(2N\le16\),所以直接枚举全排列不可行,需要做一点优化。第\(i\)个人和第\(j\)个人配对产生的快乐值,与第\(j\)......
  • 洛谷入门赛 #19 题解
    比赛传送门A-分饼干I将三盒饼干按数量排序。若较小的两盒饼干数之和大于另一盒饼干,则将较小的两盒饼干奖励给第一名,另一盒奖励给第二名;若较大的一盒饼干数大于另外两盒之和,则将较大的一盒奖励给第一名,另外两盒奖励给第二名。B-分饼干II每个人分到的饼干数都不同,即可以看......