题解 SP10079

题目大意:

  • 给定一个整数 和一个表示消息的字符串 ,找到至少出现 次的 的最长子字符串。

  • 如果存在多个解决方案,则优选最右边出现的子串(即样例 )。

  • 由多组数据,当 时输入结束。其中

  • 如果没有解决方案,则输出 ;否则,输出两个整数,用空格分隔,第一个整数表示出现至少 次的子串的最大长度; 第二个整数给出了这种子串最可能的起始位置(同时要注意**题目中字串从 开始**)。

------------------------------------------------

分析:

  • 啊,本蒟蒻不会后缀数组咋办啊……可不要忘了我们还有 +二分这种好东西!!

  • 既然我们使得至少出现 次的子串的长度尽量大,所以我们可以二分出一个 。若对其 结果为 ,则用 记录。

  • 关于 函数,我们可以每次找长度为 的字串,即 。用 存储每个子串出现的次数,若某一个子串出现数 ,则返回 ;否则返回

  • 找到 后,再计算一下它出现的位置即可。(方法与 差不多)

------------------------------------------------

Code(高清***

#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define rg register int
#define I inline int
#define V inline void
#define ll long long
#define db double
#define B inline bool
#define F1(i,a,b) for(rg i=a;i<=b;++i)
#define ed putchar('\n')
#define bl putchar(' ')
const int N=40005;
const int mod=13331;
template<typename TP>V read(TP &x)
{
    TP f=1;x=0;register char c=getchar();
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;
    for(;c>='0'&&c<='9';c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
    x*=f;
}
template<typename TP>V print(TP x)
{
    if(x<0) x=-x,putchar('-');
    if(x>9) print(x/10);
    putchar(x%10+'0');
}
int t,len,ans;
char s[N];
unsigned ll p[N],H[N];
template<typename TP>B check(TP x)
{
    map<int,int>m;
    for(rg i=1;i+x-1<=len;++i)
    {
        rg h=H[i+x-1]-H[i-1]*p[x];++m[h];
        if(m[h]>=t) return true;
    }
    return false;
}
template<typename TP>I calc(TP x)
{
    map<int,int>m;
    rg pos;
    for(rg i=1;i+x-1<=len;++i)
    {
        rg h=H[i+x-1]-H[i-1]*p[x];++m[h];
        if(m[h]>=t) pos=i;
    }
    return pos-1;//题目中从0开始 
}
int main()
{
    while(~scanf("%d",&t)&&t)
    {
        scanf("%s",s+1);
        p[0]=1,H[0]=ans=0,len=strlen(s+1);
        F1(i,1,len)
        {
            p[i]=p[i-1]*mod;
            H[i]=H[i-1]*mod+(s[i]-'a'+1);
        }
        rg l=1,r=len;
        while(l<=r)
        {
            rg mid=(l+r)>>1;
            if(check(mid)) l=mid+1,ans=mid;
            else r=mid-1;
        }
        if(!ans) puts("none");
        else print(ans),bl,print(calc(ans)),ed;
    }
    return 0;
}
全部评论

相关推荐

威猛的小饼干正在背八股:挂到根本不想整理
点赞 评论 收藏
分享
Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务