zoukankan      html  css  js  c++  java
  • Extend to Palindrome UVA

    题面就不弄了

    题意:给你一个串,让你求出补充最少的字符形成的回文串

    思路:思路很好想,就是对一个串,找其最后一个字符(第一个也行)和原串的反串的最长公共前缀,这样就求出了该串中的已有最长回文,然后把剩下部分

    倒序添加到原串上即可。

    也就是我们可以固定一个位置,即使反串的第一个单词(原串最后一个),然后从该位置向前向后遍历ht数组直到找到一个属于原串即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 2e5+10;
     9 string s;
    10 int sa[maxn],t[maxn],t2[maxn],c[maxn];
    11 
    12 void build_sa(int n,int m)
    13 {
    14     int i,*x=t,*y=t2;
    15     for(i=0; i<m; i++)c[i]=0;
    16     for(i=0; i<n; i++)c[x[i]=s[i]]++;
    17     for(i=1; i<m; i++)c[i]+=c[i-1];
    18     for(i=n-1; i>=0; i--)sa[--c[x[i]]]=i;
    19     for(int k=1; k<=n; k<<=1)
    20     {
    21         int p=0;
    22         for(i=n-k; i<n; i++)y[p++]=i;
    23         for(i=0; i<n; i++)if(sa[i] >= k)y[p++]=sa[i]-k;
    24         for(i=0; i<m; i++)c[i] = 0;
    25         for(i=0; i<n; i++)c[x[y[i]]]++;
    26         for(i=1; i<m; i++)c[i]+=c[i-1];
    27         for(i=n-1; i>=0; i--)sa[--c[x[y[i]]]] = y[i];
    28         swap(x,y);
    29         p=1,x[sa[0]]=0;
    30         for(i=1; i<n; i++)
    31             x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++;
    32         if(p>=n)break;
    33         m=p;
    34     }
    35 }
    36 
    37 int ht[maxn],rk[maxn];
    38 
    39 void getHeight(int n)
    40 {
    41     int i,j,k=0;
    42     for(i=0; i<n; i++)rk[sa[i]] = i;
    43     for(i=0; i<n-1; i++)
    44     {
    45         if(k)k--;
    46         if(s[i] == '$')continue;
    47         int j = sa[rk[i]-1];
    48         while(s[i+k] == s[j+k] && s[i+k] != '$')k++;
    49         ht[rk[i]] = k;
    50     }
    51 }
    52 
    53 char tmp[maxn];
    54 int len[3];
    55 int main()
    56 {
    57     while(~scanf("%s",tmp))
    58     {
    59         int tmp_len = strlen(tmp);
    60         s.clear();
    61         s+=tmp;
    62         s+='$';
    63         len[1] = s.length();
    64         reverse(tmp,tmp+tmp_len);
    65         s+=tmp;
    66         s+='$';
    67         len[2] = s.length();
    68         build_sa(len[2],130);
    69         getHeight(len[2]);
    70 
    71       //  for(int i=2;i<len[2];i++)printf("%d    %d===
    ",sa[i],ht[i]);
    72         int maxx = 0;
    73         int pos = rk[len[1]];
    74         int now = pos;
    75         int minn = 0x3f3f3f3f;
    76         while(now > 1 && ht[now] > maxx )
    77         {
    78             minn = min(minn,ht[now]);
    79             if(sa[now-1]+1 < len[1] && sa[now-1] + minn == len[1] - 1){maxx = minn;break;}
    80             now--;
    81         }
    82         now = pos+1;
    83         minn = 0x3f3f3f3f;
    84         while(now < len[2]&&ht[now] > maxx)
    85         {
    86             minn = min(minn,ht[now]);
    87             if(sa[now] + 1 < len[1] && sa[now]+minn == len[1] - 1){maxx = minn;break;}
    88             now++;
    89         }
    90         for(int i=tmp_len-1;i>=0;i--)printf("%c",tmp[i]);
    91         for(int i=maxx;i<tmp_len;i++)printf("%c",tmp[i]);
    92         puts("");
    93     }
    94 }
    View Code
  • 相关阅读:
    Auto.js实现自动刷视频,点赞脚本(一)
    C# 将excel文件导入到SqlServer数据库
    JavaScript实现HTML导航栏下拉菜单[悬浮显示]
    补码的知识
    指针06 零基础入门学习C语言46
    指针05 零基础入门学习C语言45
    标志寄存器01 零基础入门学习汇编语言54
    标志寄存器02 零基础入门学习汇编语言55
    标志寄存器02 零基础入门学习汇编语言55
    标志寄存器01 零基础入门学习汇编语言54
  • 原文地址:https://www.cnblogs.com/iwannabe/p/11483276.html
Copyright © 2011-2022 走看看