Palindrome - URAL - 1297(求回文串)

时间:2021-10-19 00:02:53
题目大意:RT
 
分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的。
 
线段数+后缀数组代码如下:
===========================================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = 1e4+; struct SuffixArr
{
int tempx[MAXN], tempy[MAXN], text[MAXN];
int rank[MAXN], sa[MAXN], height[MAXN], sum[MAXN];
int *x, *y, N, MaxId; void GetText(char s[])
{
N = strlen(s)*+, MaxId = ;
x = tempx, y = tempy;
int i;
for(i=; s[i]; i++)
{
text[i] = text[N-i-] = x[i] = x[N-i-] = (int)s[i];
y[i] = i, y[N-i-] = N-i-;
} text[i] = x[i] = , y[i] = i;
text[N-] = x[N-] = , y[N-] = N-; /// debug();
}
bool cmp(int i, int len)
{
if(sa[i]+len > N || sa[i-]+len > N)
return false;
if(y[sa[i]] != y[sa[i-]] || y[sa[i]+len] != y[sa[i-]+len])
return false; return true;
}
void baseSort()
{
for(int i=; i<MaxId; i++)
sum[i] = ;
for(int i=; i<N; i++)
sum[ x[ y[i] ] ] += ;
for(int i=; i<MaxId; i++)
sum[i] += sum[i-];
for(int i=N-; i>=; i--)
sa[ --sum[ x[ y[i] ] ] ] = y[i];
}
void GetSa()
{
baseSort(); for(int len=; len<=N; len<<=)
{
int id = ; for(int i=N-len; i<N; i++)
y[id++] = i;
for(int i=; i<N; i++)if(sa[i] >= len)
y[id++] = sa[i] - len; baseSort();
swap(x, y);
x[ sa[] ] = id = ; for(int i=; i<N; i++)
{
if(cmp(i, len) == true)
x[ sa[i] ] = id;
else
x[ sa[i] ] = ++id;
} MaxId = id + ; if(MaxId >= N)break;
}
}
void GetHeight()
{
for(int i=; i<N; i++)
rank[ sa[i] ] = i; for(int k=, i=; i<N; i++)
{
if(!rank[i])
{
height[] = k = ;
continue;
}
if(k)k--; int pre = sa[ rank[i]- ]; while(text[i+k] == text[pre+k])
k++;
height[rank[i]] = k;
}
/// debug();
} void debug()
{
for(int i=; i<N; i++)
printf("%d: %d\n", i, height[i]);
}
};
struct segmentTree
{
int val[MAXN], L[MAXN], R[MAXN]; void Build(int root, int l, int r, int p[])
{
L[root] = l, R[root] = r; if(l == r)
{
val[root] = p[l];
return ;
} int Mid = (l+r)>>; Build(root<<, l, Mid, p);
Build(root<<|, Mid+, r, p); val[root] = min(val[root<<], val[root<<|]);
}
int Query(int root, int u, int v)
{ if(L[root] == u && R[root] == v)
return val[root]; int Mid = (L[root]+R[root]) / ; if(v <= Mid)
return Query(root<<, u, v);
else if(u > Mid)
return Query(root<<|, u, v);
else
return min(Query(root<<, u, Mid), Query(root<<|, Mid+, v));
}
}; SuffixArr suf;
segmentTree seg;
char s[MAXN]; int main()
{
while(scanf("%s", s) != EOF)
{
int len = strlen(s)+; suf.GetText(s);
suf.GetSa();
suf.GetHeight(); seg.Build(, , suf.N-, suf.height); int MaxLen=, k=, x, y; for(int i=; i<len-; i++)
for(int j=; j<; j++)
{
if(j==)
x = suf.rank[len*-i-];
else
x = suf.rank[len*-i-]; if(i== && j)continue; y = suf.rank[i+]; if(x > y)swap(x, y); int m = seg.Query(, x+, y) * + j; if(MaxLen < m)
{
MaxLen = m;
k = i-(m+j)/+;
}
} s[k+MaxLen] = ; printf("%s\n", s+k);
} return ;
}

Palindrome - URAL - 1297(求回文串)的更多相关文章

  1. 马拉车,O&lpar;n&rpar;求回文串

    马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...

  2. &lbrack;LeetCode&rsqb; Palindrome Partitioning II 拆分回文串之二

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  3. &lbrack;LeetCode&rsqb; Find the Closest Palindrome 寻找最近的回文串

    Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'clo ...

  4. manacher算法,求回文串

    用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...

  5. Misha and Palindrome Degree CodeForces - 501E &lpar;回文串计数&rpar;

    大意: 给定字符串, 求多少个区间重排后能使原串为回文串. 先特判掉特殊情况, 对于两侧已经相等的位置之间可以任意组合, 并且区间两端点至少有一个在两侧相等的位置处, 对左右两种情况分别求出即可. # ...

  6. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...

  7. hihocoder 1032 manachar 求回文串O&lpar;n&rpar;

    #include <cstdio> #include <iostream> #include <algorithm> #include <queue> ...

  8. HDU 5371&lpar;2015多校7&rpar;-Hotaru&amp&semi;&num;39&semi;s problem&lpar;Manacher算法求回文串&rpar;

    题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...

  9. LOJ 2452 对称 Antisymmetry——用hash求回文串数

    概念 用hash求最长回文串/回文串数 首先,易知,回文串具有单调性. 如果字符串 $s[l...r]$ 为回文串串,那么 $s[x...y]$($l < x, y < r$ 且 $|l- ...

随机推荐

  1. Effective C&plus;&plus; -----条款54:让自己熟悉包括TR1在内的标准程序库

    C++ 标准程序库的主要机能由STL.iostream.locales 组成.并包含C99 标准程序库. TR1 添加了只能指针(例如 tr1::shared_ptr).一般化函数指针(tr1::fu ...

  2. Linux命令学习

    Linux命令学习 Ubuntu常用快捷键 •Ctrl+Alt+T: 打开终端 •Ctrl+Shift+T: 新建标签页 •Tab: 终端中命令补全 •Alt+数字N: 终端中切换到第N个标签页 •↑ ...

  3. 如何禁止DELETE、PUT、OPTIONS、TRACE、HEAD等协议访问应用程序 &period;

    原文:http://linder.iteye.com/blog/735435   简介 WebDAV (Web-based Distributed Authoring and Versioning)是 ...

  4. UITableView局部刷新

    只刷新cell不刷新section,这问题还难住了一阵子 需要用到: - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnima ...

  5. android 动画属性(一)之Animation

    Animation 在android 程序当中很多时候要用到动画效果,而动画效果主要是Animation来实现的,API给出的解释: 其中包含4种动画效果 AlphaAnimation 渐变透明度 R ...

  6. 2016&sol;7&sol;7 自定义函数copy

    题目:输入整数n(n<=10000),表示接下来将会输入n个实数,将这n个实数存入数组a中.请定义一个数组拷贝函数将数组a中的n个数拷贝到数组b中. 分析: (1)输入n,再输入n个实数存入数组 ...

  7. &lbrack;转&rsqb;Mysql explain用法和性能分析

    本文转自:http://blog.csdn.net/haifu_xu/article/details/16864933  from  @幸福男孩 MySQL中EXPLAIN解释命令是显示mysql如何 ...

  8. 移动App Crash的测试用例设计

    一些通用的触发移动App Crash的测试场景,如下: 1. 验证在有不同的屏幕分辨率, 操作系统 和运营商的多个设备上的App行为. 2. 用新发布的操作系统版本验证App的行为. 3. 验证在如隧 ...

  9. 不一样的go语言-error

    前言   go语言的error处理方式,在目前流行的编程语言中属于刺头.似乎天生就是用来有别于他人标记.TIOBE排行榜全十除了C语言,无一例外是try catch的阵营.而排在go之前的语言除了C与 ...

  10. Golang面向过程编程-函数

    Golang面向过程编程-函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是函数 简单的说函数的作用就是把程序里多次调用的相同的代码部分定义成一份,然后起个名字,所有的 ...