zoukankan      html  css  js  c++  java
  • Manacher模板,kmp,扩展kmp,最小表示法模板

    // Manacher算法,很好用。

    char
    s[2*N]; //储存临时串 int save[2*N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); int cnt=0; for(int i=0;i<len;i++) { s[cnt++]='#'; s[cnt++]=tmp[i]; } s[cnt++]='#'; memset(save,0,sizeof(save)); int a=0,p=0; int mx=1; for(int i=1;i<cnt-1;i++) { if(i>=p) { int num=1; while(i+num<cnt&&i-num>=0&&s[i+num]==s[i-num]) { num++; } p=i+num-1; //能到达的最远位置 a=i; save[i]=num-1; //从这个位置出发最长的回文 if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } else { int j=2*a-i; if( i+save[j] < p) { save[i]=save[j]; if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } else { int k=2*i-p; while(p+1<cnt&&k-1>=0&&s[p+1]==s[k-1]) { p++; k--; } a=i; save[i]=p-i; if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } } } return mx; }

    kmp,扩展kmp

    // 感觉kmp可以理解。 
    
    #define N 100010
    int s[N];
    int next[N];
    int t[N];
    
    int main()
    {
        //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
        //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)
                scanf("%d",s+i);
            for(int i=0;i<m;i++)
                scanf("%d",t+i);
        ///////////////求next
            int j=0;
            next[0]=0;
            for(int i=1;i<m;i++)
            {
                while(j!=0&&t[j]!=t[i]) j=next[j-1]; 
                if(t[j]==t[i]) j++;
                next[i]=j;
            }
    
        ///////////////////// 
    
            j=0;
            int ans=-1;
            for(int i=0;i<n;i++)
            {
                while(j!=0&&s[i]!=t[j]) j=next[j-1];
                if(s[i]==t[j]) j++;
                if(j==m)
                {
                    ans=i+1-m+1;
                    break;
                }
            }
    
        ///////////////////
            if(ans==-1)
                printf("-1
    ");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
    
    
    // 扩展kmp。
    #defien N 100100
    
    int next[N],sum[N];// sum用来记录
    
    void build(char s[])
    {
        memset(next,0,sizeof(next));
        int p=0,a=0;
        next[0]=len;
        for(int i=1;i<len;i++)
        {
            if(i+next[i-a]-1<p)
            {
                next[i]=next[i-a];
            }
            else
            {
                int k=p-i;
                while(p+1<len && s[p+1]==s[k+1])
                {
                    p++; k++;
                }
                p=max(p,i);
                next[i]=k+1;
                a=i;
            }
        }
    }
    
    void extend_kmp(char s[],char t[])//求从s到t上的最大前缀
    {
        memset(sum,0,sizeof(sum));
        int p=-1,a=0;
        for(int i=0;i<len;i++)
        {
            if(i+next[i-a]-1<p)
            {
                sum[i]=next[i-a];
            }
            else
            {
                int k=p-i;
                while(p+1<len && s[p+1]==t[k+1])
                {
                    p++; k++;
                }
                p=max(p,i);
                sum[i]=k+1;
                a=i;
            }
        }
    }

    最小表示法

    int mistr(char s[],int len)  //输入一串字符,返回最小表示法的起始位置
    {
        int i=0,j=1,k=0;
        while(i<len&&j<len&&k<len)
        {
            if(s[i+k]==s[j+k])
            {
                k++;
            }
            else
            {
                if(s[i+k] > s[j+k]) i=i+k+1;
                if(s[i+k] < s[j+k]) j=j+k+1;
                k=0;
                if(i==j) j++;
            }
        }
        return min(i,j);
    }
  • 相关阅读:
    构建之法阅读笔记
    10个操作数的随机四则运算测试
    poj 1742 Coins (动态规划,背包问题)
    第二周进度报告
    蓝桥杯 2015年省赛最后一题 生命之树(树形dp)
    蓝桥杯 ALGO-108 最大体积 (动态规划)
    蓝桥杯 algo——6 安慰奶牛 (最小生成树)
    蓝桥杯 algo_5 最短路 (bellman,SPFA)
    蓝桥杯 ALGO-4 结点选择 (树形动态规划)
    软件工程——评价搜狗拼音输入法
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3226717.html
Copyright © 2011-2022 走看看