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 ...
随机推荐
- @bzoj - 4951@ [Wf2017]Money for Nothing
目录 @description@ @solution@ @accepted code@ @details@ @description@ 在这道题种你需要解决一个全世界人类从存在起就在面临的最深刻的问题 ...
- JavaScript--淘宝图片切换
css样式有点问题,但是主要是js逻辑: <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...
- Puppet基础
基础架构图介绍 自动化运维框架: 自动化监控: puppet介绍 常用的批量工具介绍: OS Provisioning:PXE,Cobbler OS Configuration:ansible,pu ...
- 阿里云OSS同城冗余存储正式商业化,提供云上同城容灾能力
近日,阿里云正式发布OSS同城冗余存储产品.这是国内目前提供同城多AZ冗余部署能力覆盖最广的云上对象存储产品,可以实现云存储的同城双活,满足企业级客户对于“发生机房级灾难事件时数据不丢失,业务不中断” ...
- 王坚十年前的坚持,才有了今天世界顶级大数据计算平台MaxCompute
如果说十年前,王坚创立阿里云让云计算在国内得到了普及,那么王坚带领团队自主研发的大数据计算平台MaxCompute则推动大数据技术向前跨越了一大步. 数据是企业的核心资产,但十年前阿里巴巴的算力已经无 ...
- @loj - 2507@ 「CEOI2011」Matching
目录 @description@ @solution@ @accepted code@ @details@ @description@ 对于整数序列 \((a_1, a_2, ..., a_n)\) ...
- php配置文件php.ini中文详解
转自:http://www.cnblogs.com/hbl/archive/2008/02/15/1069367.html [PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而p ...
- 算法导论笔记:18B树
磁盘作为辅存,它的容量要比内存大得多,但是速度也要慢许多,下面就是磁盘的的结构图: 磁盘驱动器由一个或多个盘片组成,它们以固定的速度绕着主轴旋转,数据存储于盘片的表面,磁盘驱动器通过磁臂末尾的磁头来读 ...
- web项目的文件上传和 下载
文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用Java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...
- git 生成秘钥连接远程仓库
二.打开GitBash ,用cd命令进入本地项目目,然后把初始化一下,把本地的目录变成git本地仓库, git status 可以查看本地目录的状态信息 git init git status 三.将 ...