[NOIP模拟题]FGD的密码
来源:互联网 发布:淘宝订单在线生成器 编辑:程序博客网 时间:2024/05/17 08:26
Description
FGD的眼睛瞪得像苹果,他还计划中午回到母舰去他家旁边的咖啡厅去喝一杯呢。看来咖啡是暂时泡汤了。
“据说,为了预防日益增加的逃兵问题,这战机的引擎没有舰长的命令,是无法关闭,只能向前的。”
“好!现在我下令让他关闭!”
“可是,我们都不知道该怎么关掉他。”
……
FGD走到动力舱,一脚踢开在控制台上焦头烂额的工程师,自己坐了上去。
一小时后……
FGD发现每当他想关闭引擎的时候,就会有一大堆乱码跳出来,他便会不由自主地去阅读那一大段无规律的文字,阻止他的正常思维,使得他没有空闲时间去按下对话框的确定。
一天后……
FGD终于有点头绪了,他发现这段文字并不是完全漫无规律的,这段仅仅由小写字母组成的文字可以被分为长度相同的若干行,每行都有一串相同的连续的文字,隐藏在其他乱码中间。FGD以他敏锐的大脑相信,那段最长的被重复的文字一定包含有惊天的大秘密。现在你帮忙告诉他那段文字的长度吧。
Input
输入文件第一行为两个整数
接下来
Output
要求输出文件仅包含一行,一个整数,为这
Sample Input
2 5
ababc
cabac
Sample Output
3
HINT
思路
首先将几个串连在一起,然后把最长不重叠子串改一改就好了。
代码
#include <cstdio>#include <algorithm>const int maxn=300000;char s[maxn+10],t[maxn+10];int m,len,pos[maxn+10];struct suffix_array{ int rank[maxn+10],sa[maxn+10],sum[maxn+10],tmp[maxn+10],h[maxn+10]; inline int suffix_sort(int n) { int m=127,p=1,len=1; int* x=rank; int* y=tmp; for(register int i=1; i<=n; ++i) { x[i]=s[i]; y[i]=i; ++sum[x[i]]; } for(register int i=1; i<=m; ++i) { sum[i]+=sum[i-1]; } for(register int i=n; i; --i) { sa[sum[x[i]]]=i; --sum[x[i]]; } while(p<n) { m=p; p=0; for(register int i=0; i<=m; ++i) { sum[i]=0; } for(register int i=n-len+1; i<=n; ++i) { ++p; y[p]=i; } for(register int i=1; i<=n; ++i) { if(sa[i]-len>0) { ++p; y[p]=sa[i]-len; } } for(register int i=1; i<=n; ++i) { ++sum[x[y[i]]]; } for(register int i=1; i<=m; ++i) { sum[i]+=sum[i-1]; } for(register int i=n; i; --i) { sa[sum[x[y[i]]]]=y[i]; --sum[x[y[i]]]; } std::swap(x,y); p=1; x[sa[1]]=1; for(register int i=2; i<=n; ++i) { if(!((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+len]==y[sa[i-1]+len]))) { ++p; } x[sa[i]]=p; } len<<=1; } p=0; for(register int i=1; i<=n; ++i) { ++p; rank[sa[i]]=p; } return 0; } inline int get_height(int n) { int k=0; for(register int i=1; i<=n; ++i) { if(k) { --k; } int j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) { ++k; } h[rank[i]]=k; } return 0; } inline int judge(int x,int n) { int b[11],cnt=1; for(register int i=1; i<=m; ++i) { b[i]=0; } b[pos[sa[1]]]=1; for(int i=2; i<=n; ++i) { if(h[rank[sa[i]]]<x) { for(register int j=1; j<=m; ++j) { b[j]=0; } cnt=1; b[pos[sa[i]]]=1; } else if(!b[pos[sa[i]]]) { b[pos[sa[i]]]=1; ++cnt; } if(cnt>=m) { return 1; } } return 0; } inline int work(int n) { suffix_sort(n); get_height(n); int left=0,right=len; while(left<=right) { int mid=(left+right)>>1; if(judge(mid,n)) { left=mid+1; } else { right=mid-1; } } return left-1; }};suffix_array sa;int main(){ scanf("%d%d",&m,&len); int x=0; for(register int i=1; i<m; ++i) { scanf("%s",t+1); for(register int j=1; j<=len; ++j) { s[x+j]=t[j]; pos[x+j]=i; } x+=len+1; s[x]='~'; } scanf("%s",t+1); for(register int i=1; i<=len; ++i) { s[x+i]=t[i]; pos[x+i]=m; } x+=len; printf("%d\n",sa.work(x)); return 0;}
阅读全文
0 0
- [NOIP模拟题]FGD的密码
- 【noip模拟赛】密码
- FGD
- fgd
- fgd
- 叉姐的Noip模拟题
- [Noip模拟题]绿豆蛙的归宿
- NOIP 模拟题 奇怪的字符串
- NOIP 模拟题 小G的城堡
- NOIP 模拟题 消失的数字
- 【动态规划】[NOIP 模拟赛]密码
- noip模拟赛(一)密码
- NOIP模拟题
- 【lcyz】noip模拟题
- NOIP模拟题题解
- 【NOIP模拟题】最大公约数
- 【NOIP模拟题】连通
- 【noip模拟题】数列
- leetcode 493. Reverse Pairs
- Oracle连接DB2
- "下载软件仓库信息失败,检查您的internet连接"的解决办法
- Android Databinding 点击事件
- MYSQL把一张表的数据批量复制到另外一张表
- [NOIP模拟题]FGD的密码
- 【android逆向笔记】(一)简单登录逆向
- 利用键盘输入 统计随机输入 一段话中某个元素出现的次数 (详细思路)
- 火狐浏览器的兼容性问题
- STM32 F105 USB CDC host
- Linux下网络编程笔记(一)
- 微信小程序获取用户手机号详解
- 线性表的链式存储实现c语言
- Intellij Idea2016.2开发工具注册