URAL1297 Palindrome(后缀数组)

求一个串的最大回文字串。

可以用后缀数组解决。

分别考虑奇数和偶数回文子串的情况,枚举原串S的每个位置i作为中间位置看其能向左右两边同时拓展都哪儿:把原串S反转成S‘,拼接SaS‘(a为一个特殊字符),最远拓展的地方便可以通过LCP(suffix[i],suffix[i‘])求得,i‘为i对应在S‘的位置。

另外题目要求第一个出现的最长回文串,从左到右枚举中间位置得到的肯定就是出现最早的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 2222
 7
 8 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
 9 int cmp(int *r,int a,int b,int l){
10     return r[a]==r[b] && r[a+l]==r[b+l];
11 }
12 int sa[MAXN],rank[MAXN],height[MAXN];
13 void SA(int *r,int n,int m){
14     int *x=wa,*y=wb;
15
16     for(int i=0; i<m; ++i) ws[i]=0;
17     for(int i=0; i<n; ++i) ++ws[x[i]=r[i]];
18     for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
19     for(int i=n-1; i>=0; --i) sa[--ws[x[i]]]=i;
20
21     int p=1;
22     for(int j=1; p<n; j<<=1,m=p){
23         p=0;
24         for(int i=n-j; i<n; ++i) y[p++]=i;
25         for(int i=0; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j;
26         for(int i=0; i<n; ++i) wv[i]=x[y[i]];
27         for(int i=0; i<m; ++i) ws[i]=0;
28         for(int i=0; i<n; ++i) ++ws[wv[i]];
29         for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
30         for(int i=n-1; i>=0; --i) sa[--ws[wv[i]]]=y[i];
31         swap(x,y); x[sa[0]]=0; p=1;
32         for(int i=1; i<n; ++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
33     }
34
35     for(int i=1; i<n; ++i) rank[sa[i]]=i;
36     int k=0;
37     for(int i=0; i<n-1; height[rank[i++]]=k){
38         if(k) --k;
39         for(int j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k);
40     }
41 }
42
43 int st[12][MAXN];
44 void ST(int *a,int n){
45     for(int i=1; i<=n; ++i) st[0][i]=a[i];
46     for(int i=1; i<12; ++i){
47         for(int j=1; j<=n; ++j){
48             if(j+(1<<i)>n) break;
49             st[i][j]=min(st[i-1][j],st[i-1][j+(1<<i-1)]);
50         }
51     }
52 }
53 int rmq(int a,int b){
54     if(a>b) swap(a,b);
55     ++a;
56     int k=(int)(log2(b-a+1)+1e-6);
57     return min(st[k][a],st[k][b-(1<<k)+1]);
58 }
59
60 char str[MAXN];
61 int r[MAXN];
62 int main(){
63     scanf("%s",str);
64     int n=strlen(str);
65     for(int i=0; i<n; ++i) r[i]=str[i];
66     r[n]=1;
67     for(int i=n-1; i>=0; --i) r[n+n-i]=str[i];
68     r[n<<1|1]=0;
69     SA(r,(n<<1|1)+1,128);
70     ST(height,n<<1|1);
71     int res=0;
72     int posi,flag;
73     for(int i=0; i<n; ++i){
74         if(res<(rmq(rank[i],rank[n+n-i])-1<<1)+1){
75             res=(rmq(rank[i],rank[n+n-i])-1<<1)+1;
76             posi=i; flag=0;
77         }
78         if(i && res<(rmq(rank[i],rank[n+n-i+1])<<1)){
79             res=(rmq(rank[i],rank[n+n-i+1])<<1);
80             posi=i; flag=1;
81         }
82     }
83     if(flag){
84         for(int i=(res>>1); i>=1; --i) putchar(str[posi-i]);
85         for(int i=0; i<(res>>1); ++i) putchar(str[posi+i]);
86     }else{
87         for(int i=(res>>1); i>=1; --i) putchar(str[posi-i]);
88         putchar(str[posi]);
89         for(int i=1; i<=(res>>1); ++i) putchar(str[posi+i]);
90     }
91     return 0;
92 }
时间: 2024-11-06 04:29:17

URAL1297 Palindrome(后缀数组)的相关文章

URAL1297:Palindrome(后缀数组)

Description The "U.S. Robots" HQ has just received a rather alarming anonymous letter. It states that the agent from the competing ?Robots Unlimited? has infiltrated into "U.S. Robotics". ?U.S. Robots? security service would have alrea

URAL 1297 Palindrome 后缀数组

1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The "U.S. Robots" HQ has just received a rather alarming anonymous letter. It states that the agent from the competing ?Robots Unlimited? has infiltrated into "U.S. Robotics".

URAL 1297. Palindrome(后缀数组求最大回文串)

题目大意:给你一串字符串,让你求出来它存在的最长连续的回文串. 解题思路:先把字符串逆序加到数组中,然后用后缀数组求解.两种方法:1,枚举排名,直接比较rank相同的字符串的位置差是不是len.如果是的话,就记录求解:2,枚举地址,求第i地址与第2*len-i+1的lcp的最大值. PS:需要注意如果多解输出靠前的字符串. 两种写法写在了一起,分别是Del,和Del1函数. 1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB T

URAL - 1297 Palindrome(后缀数组求最长回文子串)

Description The "U.S. Robots" HQ has just received a rather alarming anonymous letter. It states that the agent from the competing ?Robots Unlimited? has infiltrated into "U.S. Robotics". ?U.S. Robots? security service would have alrea

URAL 1297 Palindrome (后缀数组+RMQ)

题意:给定一个字符串,求一个最长的回回文子串,多解输出第一个. 析:把字符串翻转然后放到后面去,中间用另一个字符隔开,然后枚举每一个回文串的的位置,对第 i 个位置,那么对应着第二个串的最长公共前缀, 求最长公共子串,可以用RMQ解决. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cst

【后缀数组|最长回文子串】URAL-1297 Palindrome

1297.Palindrome Time limit: 1.0 second Memory limit: 64 MB The "U.S. Robots" HQ has just received a rather alarming anonymous letter. It states that the agent from the competing ?Robots Unlimited? has infiltrated into "U.S. Robotics".

Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)

1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlimited» has infiltrated into “U.S. Robotics”. «U.S. Robots»

URAL 1297. Palindrome(输出最长回文子串--后缀数组)

Input The input consists of a single line, which contains a string of Latin alphabet letters (no other characters will appear in the string). String length will not exceed 1000 characters. Output The longest substring with mentioned property. If ther

URAL 1297. Palindrome(后缀数组 求最长回文子串)

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1297 1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The "U.S. Robots" HQ has just received a rather alarming anonymous letter. It states that the agent from the competing ?Robots