• hiho1602本质不同的回文子串的数量


    给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串?

    注意如果两个位置不同的子串满足长度相同且对应字符也都相同,则认为这两个子串本质上是相同的。

    Input

    一个只包含小写字母的字符串S。

    对于30%的数据,S长度不超过100。

    对于60%的数据,S长度不超过1000。

    对于100%的数据,S长度不超过800000。

    Output

    回文子串的数量

    Sample Input

    abbab

    Sample Output

    5

    马拉车算法+bkrdhash:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    #define ULL unsigned long long
    const int maxn=2000000+20;
    ULL P = 1313131;
    ULL sqr[maxn/2],has[maxn/2],V[maxn];
    
    int Laxt[maxn],Next[maxn],cnt=0;
     
    const int MOD = 2000007;
    
    bool _insert(ULL Now)
    {
           int u=Now%MOD;
           for(int i=Laxt[u];i;i=Next[i]){
            if(V[i]==Now) return true;
           }
           Next[++cnt]=Laxt[u];
           Laxt[u]=cnt;
           V[cnt]=Now;
           return false;
    }
    int ans=0;void _hash(int x,int y){
        ULL Now=has[y]-has[x-1]*sqr[y-x+1];
        if(!_insert(Now)) ++ans;
    } 
    void _malacher()
    {
        int R=0,Mid=0,Len;
        char c[maxn];
        scanf("%s",c+1);
        Len=strlen(c+1);
        sqr[0]=1;
        for(int i=1;i<=Len;i++){
            sqr[i]=sqr[i-1]*P;
            has[i]=has[i-1]*P+c[i];
        }  
        int r[maxn];
         for(int i=1;i<=Len;++i) {      
            _hash(i,i);
            if(R>i) r[i]=min(r[2*Mid-i],R-i);
            while(i+r[i]+1<=Len&&c[i+r[i]+1]==c[i-r[i]-1]){
                _hash(i-r[i]-1,i+r[i]+1);
                r[i]++;
            }
            if(i+r[i]>R) {
                R=i+r[i];
                Mid=i;
            }
        }
        
        cnt=0;Mid=0;R=0;
        memset(Laxt,0,sizeof(Laxt));
        memset(r,0,sizeof(r));
        for(int i=2;i<=Len;++i) {
            if(R>i) r[i]=min(r[2*Mid-i],R-i+1);
            while(i+r[i]<=Len&&c[i+r[i]]==c[i-r[i]-1]) {
                _hash(i-r[i]-1,i+r[i]);
                ++r[i];
            }
            if(i+r[i]-1>R) {
                R=i+r[i]-1;
                Mid=i;
            }
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        _malacher();
        return 0;
    }
  • 相关阅读:
    Canvas中的save方法和restore方法
    python之函数默认参数的坑
    python之函数名的应用
    python之golbal/nonlocal
    python之*的魔性用法
    python之函数的传参形参的第三种动态参数*args和**kwargs
    python之道09
    python之函数的初识
    python之道08
    python之99乘法表
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7714475.html
Copyright © 2020-2023  润新知