暑期个人赛--第十一场--B(字符串哈希 Karp-Rabin)

来源:互联网 发布:cms视频监控客户端手机 编辑:程序博客网 时间:2024/05/17 02:05

时间限制 10000 ms 内存限制 65536 KB

题目描述

田田被老师要求背诵一个字符串,田田刚刚背了一个子串,说他记性差他还不承认,背下这个子串后却忘了这个子串是从哪里开始的。
现在田田把这个字符串给你,并且让你告诉他至少一次背多长的子串才不可能产生歧义,即不存在另一个子串与它相等

输入格式

输入仅一行,即要求田田背诵的字符串
长度<=10^6

输出格式

输出一行,即不产生歧义串的最小串长

输入样例

abcdabcd

输出样例

5

赛中提交:NULL


赛后AC:YES


反省:

赛后早上起来三十分钟敲完一遍AC....

哭晕在厕所......

比赛中的时候其实也把代码给敲了出来了,

但是一看题目意思觉得不对,以为是“求出一个绝对不会有重复子串的长度”

而自己苦思冥想也觉得,这个题意的话必须得要n^3

然后就一直卡着卡了一个小时....

结果出来后问翔他告诉我题意应该是“找出一个没有其他子串与他相同的子串,并输出他的长度”

..............................................................

我现在还是觉得题意应该是前一种...



下面是AC代码

#include <iostream>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <memory.h>#include <string>#include <vector>#include <list>#include <map>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <numeric>#include <functional>#define maxn 1000005#define mod 100007 using namespace std;typedef unsigned long long ll;char a[maxn];ll h[maxn]; int main(){    scanf("%s",a);    int slen=strlen(a);    memset(h,0,sizeof(h));     h[0]=a[0];    for(int i=1;i<slen;i+=1){        h[i]=h[i-1]*mod+a[i];    }     for(int l=1;l<=slen;l+=1){        ll base=1;        for(int j=0;j<l;j+=1){            base*=mod;        }         ll tmp1=0,tmp2=0;        bool flag=true;        tmp1=h[l-1];        tmp2=tmp1%mod;        vector<ll> g[mod];        g[tmp2].push_back(tmp1);        for(int i=0;i+l<slen;i+=1){            tmp1=h[i+l]-h[i]*base;            tmp2=tmp1%mod;             if(g[tmp2].empty()){                g[tmp2].push_back(tmp1);            }            else{                int sz=g[tmp2].size();                int j=0;                for(;j<sz;j+=1){                    if(g[tmp2][j]==tmp1) break;                }                 if(j==sz){                    g[tmp2].push_back(tmp1);                }                else{  //若有重复,则直接跳出i的循环,结束当前次l的循环                    flag=false;                    break;                }            }        }        if(flag){            printf("%d\n",l);            break;        }    }     return 0;}



0 0
原创粉丝点击