UVA - 11475 Extend to Palindrome (后缀数组)
Your task is, given an integer N, to make a palidrome (word that reads the same when you reverse it) of length at least N. Any palindrome will do. Easy, isn’t it? That’s what you thought before you passed it on to your inexperienced team-mate. When the contest is almost over, you find out that that problem still isn’t solved. The problem with the code is that the strings generated are often not palindromic. There’s not enough time to start again from scratch or to debug his messy code. Seeing that the situation is desperate, you decide to simply write some additional code that takes the output and adds just enough extra characters to it to make it a palindrome and hope for the best. Your solution should take as its input a string and produce the smallest palindrome that can be formed by adding zero or more characters at its end. Input Input will consist of several lines ending in EOF. Each line will contain a non-empty string made up of upper case and lower case English letters (‘A’-‘Z’ and ‘a’-‘z’). The length of the string will be less than or equal to 100,000. Output For each line of input, output will consist of exactly one line. It should contain the palindrome formed by adding the fewest number of extra letters to the end of the corresponding input string. Sample Input aaaa abba amanaplanacanal xyz Sample Output aaaa abba amanaplanacanalpanama
题意:
在字符串末尾附加最少的字母,使其成为回文串。
思路:
求得字符串结尾处的回文串长度,保持结尾处回文串不变,其他的翻转一下即可。
注意使用后缀数组时,要对后缀的起始位置进行约束,否则会出错,如:aaaaaaabaaaa
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cerr<<#x<<" = "<<x<<endl;
#define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); char s[maxn];
int len, Rank[maxn], sa[maxn], tlen, tmp[maxn]; bool compare_sa(int i, int j) {
if (Rank[i] != Rank[j]) { return Rank[i] < Rank[j]; }
//如果以i开始,长度为k的字符串的长度,已经超出了字符串尾,那么就赋值为-1
//这是因为,在前面所有数据相同的情况下,字符串短的字典序小.
int ri = i + tlen <= len ? Rank[i + tlen] : -inf;
int rj = j + tlen <= len ? Rank[j + tlen] : -inf;
return ri < rj;
} void construct_sa() {
//初始的RANK为字符的ASCII码
for (int i = ; i <= len; i++) {
sa[i] = i;
Rank[i] = i < len ? s[i] : -inf;
}
for (tlen = ; tlen <= len; tlen *= ) {
sort(sa, sa + len + , compare_sa);
tmp[sa[]] = ;
//全新版本的RANK,tmp用来计算新的rank
//将字典序最小的后缀rank计为0
//sa之中表示的后缀都是有序的,所以将下一个后缀与前一个后缀比较,如果大于前一个后缀,rank就比前一个加一.
//否则就和前一个相等.
for (int i = ; i <= len; i++) {
tmp[sa[i]] = tmp[sa[i - ]] + (compare_sa(sa[i - ], sa[i]) ? : );
}
for (int i = ; i <= len; i++) {
Rank[i] = tmp[i]; }
}
} int height[maxn]; void construct_lcp() {
// for(int i=0;i<=n;i++){Rank[sa[i]]=i;}
int h = ;
height[] = ;
for (int i = ; i < len; i++) {//i为后缀数组起始位置
int j = sa[Rank[i] - ];//获取当前后缀的前一个后缀(排序后)
if (h > )h--;
for (; j + h < len && i + h < len; h++) {
if (s[j + h] != s[i + h])break;
}
height[Rank[i]] = h;
}
} int st[maxn][]; void rmq_init() {
for (int i = ; i <= len; i++) {
st[i][] = height[i];
}
int l = ;
for (int i = ; l <= len; i++) {
for (int j = ; j + l / <= len; j++) {
st[j][i] = min(st[j][i - ], st[j + l / ][i - ]);
}
l <<= ;
}
} int ask_min(int i, int j) {
int k = int(log(j - i + 1.0) / log(2.0));
return min(st[i][k], st[j - ( << k) + ][k]);
} int lcp(int a, int b)//此处参数是,原字符串下标
{
a = Rank[a], b = Rank[b];
if (a > b)
swap(a, b);
return ask_min(a + , b);
} int solve(){
int ans=,pos=;
for(int i=;i<=len;i++){
if(sa[i]==len/+){
pos=i;
break;
}
}
int mn=inf;
for(int i=pos+;i<=len;i++){
mn=min(height[i],mn);
if(sa[i]==len/-mn){
ans=max(mn,ans);
}
}
mn=inf;
for(int i=pos;i>=;i--){
mn=min(height[i],mn);
if(sa[i-]==len/-mn){
ans=max(mn,ans);
}
} return ans; } int main() {
// ios::sync_with_stdio(false);
// freopen("in.txt", "r", stdin); while (scanf("%s",s)!=EOF){
len=strlen(s);
s[len]='$';
for(int i=;i<len;i++){
s[len*-i]=s[i];
} len=len*+;
height[len+]=;
s[len]=;
construct_sa();
construct_lcp();
int l=,r=len;
int ans=solve();
len/=;
int tmps=len-ans;
for(int i=;i<tmps;i++){
s[len+i]=s[len-ans-i-];
}
s[len+tmps]=;
printf("%s\n",s);
} return ;
}
UVA - 11475 Extend to Palindrome (后缀数组)的更多相关文章
- uva 11475 - Extend to Palindrome(KMP)
option=com_onlinejudge&Itemid=8&category=506&page=show_problem&problem=2470" ta ...
- UVA 11475 Extend to Palindrome(后缀数组+ST表)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/27647 [题目大意] 给出一个字符串,要求在其后面添加最少的字符数,使得其成为一个回文串.并输出这个回文串 ...
- UVA - 11475 Extend to Palindrome —— 字符串哈希 or KMP or 后缀数组
题目链接:https://vjudge.net/problem/UVA-11475 题意: 给出一个字符串,问在该字符串后面至少添加几个字符,使得其成为回文串,并输出该回文串. 题解: 实际上是求该字 ...
- UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
题目链接:点击打开链接 题意:给你一个串,让你在串后面添加尽可能少的字符使得这个串变成回文串. 思路:这题可以kmp,manacher,后缀数组三种方法都可以做,kmp和manacher效率较高,时间 ...
- UVA 11475 Extend to Palindrome(hash)题解
题意:问你最少加几个字母使所给串变成回文串. 思路:一开始打算将正序和逆序都hash,然后用提取前缀后缀的方法来找,但是RE了,debug失败遂弃之.后来发现可以直接hash,一边hash一边比较.我 ...
- UVA 11475 Extend to Palindrome hash
题意: 给出一个字符串,让你往后添加最少的字符,使其成为回文串. 分析: 题目就相当于求后缀字符串为回文串的最长长度,判断回文串要O(n)时间,直接判断肯定不行.我们从后往前枚举,每次字符串与上一个字 ...
- UVa 11475 - Extend to Palindrome
題目:給你一個字符串,在後面拼接一部分使得它變成回文串,使得串最短.輸出這個回文串. 分析:KMP,dp.這裡利用KMP算法將串和它的轉置匹配,看結束時匹配的長度就可以. 因為串比较長.使用KMP比较 ...
- URAL 1297 Palindrome 后缀数组
D - Palindrome Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- URAL - 1297 Palindrome —— 后缀数组 最长回文子串
题目链接:https://vjudge.net/problem/URAL-1297 1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB ...
随机推荐
- 洛谷 P1119 灾后重建 最短路+Floyd算法
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1119 灾后重建 题目描述 B地区在地震过后,所有村 ...
- nodeJs学习-09 模板引擎 jade、ejs
模板引擎: jade -破坏式.侵入式,强依赖:用了之后不能随便用别的引擎 ejs - 温和.非侵入时.弱依赖 jade使用 const jade = require('jade'); var str ...
- 并发编程之submit和execute区别
前言 使用线程池难免会用到submit和execute,但是submit是有坑的,此处做个记录 1.submit坑 此处随便写一个方法,进入内部查看execute和submit /** * @Auth ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...
- 使用 Linux Centos Docker 安装 2Bizbix
在 Docker 安装 2Bizbix 安装 Centos 7 安装 mysql5.5 镜像 映射好数据库的配置文件和数据库目录 在 Windows 安装 2Bizbox 安装 jboss/base- ...
- ios开发――解决UICollectionView的cell间距与设置不符问题
在用UICollectionView展示数据时,有时我们希望将cell的间距调成一个我们想要的值,然后查API可以看到有这么一个属性: - (CGFloat)minimumInteritemSpaci ...
- Spring Security入门篇——标签sec:authorize的使用
Security框架可以精确控制页面的一个按钮.链接,它在页面上权限的控制实际上是通过它提供的标签来做到的 Security共有三类标签authorize authentication accessc ...
- oracle函数 chartorowid(c1)
[功能]转换varchar2类型为rowid值 [参数]c1,字符串,长度为18的字符串,字符串必须符合rowid格式 [返回]返回rowid值 [示例] SELECT chartorowid('AA ...
- Redis源码解析:06整数集合
整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现. intset可以保存类型为int16_t,i ...
- Python基础:19类和实例的内建函数
1:issubclass() issubclass()布尔函数,判断一个类是否是另一个类的子类或子孙类.它有如下语法:issubclass(sub,sup) 这个函数也允许“不严格”的子类,意味着,一 ...