Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化

Ural Federal University Contest, SKB Kontur Cup

Petrozavodsk Winter Training Camp, Saturday, February 2, 2013

Problem D. Five Palindromes

Input file: input.txt

Output file: output.txt

Time limit: 2 seconds (3 seconds for Java)

Memory limit: 256 mebibytes

Your task is to divide a string into five non-empty palindromes.

Input

The input contains one string consisting of n lowercase English letters (5 6 n 6 105).

Output

Output “NO” if such division is impossible. Otherwise, output “YES” on the first line, and the next five

lines should contain one palindrome each, which, if concatenated in this order, form the given string.

Examples

input.txt                                   output.txt

aaabbcdcaa                          YES

aa

a

bb

cdc

aa

spaaaaaaarta                       NO

abacdcxyxzpz                         NO

Source

Petrozavodsk Winter-2013. Ural FU Contest

My Solution

manacher、一个串切割成5个回文子串、优化

第一次使用manacher 嘿嘿??

为了方便处理奇偶的情况, 我们把 区间 [ i , j ] 的回文子串半径保存在 len[ i + j ] 里,

if(len[ i + j ] >= (j - i)/2 + 1) 则[ i , j ] 为回文串

可以O(n)的处理出len 所有中心的回文子串长度

这里先跑一边 manacher(n) 得到 len[]数组

然后O(n) 的预处理出 第一个字符串的右端点 i,放在一个队列里

并且O(n) 的预处理出 最后一个字符串的左端点 j,放在一个vector里

对于每一个 i, 把所有 (i < j)的j跑一遍

并且判断[ i+1, j -1 ] 是否有回文子串 [ i + 1, k ],  [ k + 1, u ],  [ u + 1, j - 1 ] 如果满足条件则输出并且用 return 0; 或者 exit(0)直接结束程序

否则跑完所有情况都没有符合要求的答案则 "NO"

复杂度 不知道怎么算 大概 nlogn的, 如果不预处理出那些东西最糟糕的复杂度可能 O(n^2) TLE 23,预处理后大概最好的情况 O(n), 最差的情况O(nlogn)左右

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

int len[2*maxn];
char str[maxn];

inline void manacher(int n)
{
    int p, q, r;
    len[0] = 1;
    for(int i = 1, j = 0; i < (n << 1) - 1; i++){
        p = i >> 1, q = i - p, r = ((j + 1) >> 1) + len[j] - 1;
        len[i] = r < q ? 0 : min(r - q + 1, len[(j << 1) - i]);
        while(p > len[i] - 1 && q + len[i] < n && str[p - len[i]]
              == str[q + len[i]])
                len[i]++;
        if(q + len[i] - 1 > r)
            j = i;
    }
}

queue<int> que;
vector<int> vec;

int main()
{

    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #ifdef LOCAL
    int T = 3;
    while(T--){
    #endif // LOCAL
    scanf("%s", str);
    int n = strlen(str);
    manacher(n);
    //for(int i = 0; i < 2*n; i++)
    //cout<<str<<endl;
    for(int i = 0; i < n; i++){
        if(i == 0 || len[0 + i] >= (i - 0) / 2 + 1){que.push(i);}
    }
    for(int i = n-1; i >= 0; i--){
        if(i == n - 1 || len[n - 1 + i] >= (n - 1 - i) / 2 + 1){vec.push_back(i);}
    }

    int szv = vec.size(), i, j;

    while(!que.empty()){
        i = que.front();
        que.pop();
        for(int x = 0; x < szv; x++){
            j = vec[x];
            if(j <= i) break;
    //!
            for(int k = i + 1; k < j; k++){
                if(k == i + 1 || len[i + 1 + k] >= (k - (i+1)) / 2 + 1){
                    for(int u = k + 1; u < n; u++){
                        if(u == k + 1 || len[k + 1 + u] >= (u - (k+1)) / 2 + 1){
                            if(len[u + 1 + j - 1] >= (j - 1 - (u + 1)) / 2 + 1){
                                printf("YES\n");
                                for(int v = 0; v < n; v++){
                                    putchar(str[v]);
                                    if(v == i || v == j-1 || v == k || v == u) putchar('\n');
                                }
                                putchar('\n');
                                return 0;
                            }
                        }
                        //else break;
                    }
                }
                //else break;
            }

        }
        //else break;

    }
    printf("NO\n");

    #ifdef LOCAL
    vec.clear();
    printf("\n");
    }
    #endif // LOCAL
    return 0;
}

Thank you!

------from ProLights

时间: 2024-10-22 22:22:54

Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化的相关文章

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 后缀数组:求最长回文子串

思路:这题下午搞了然后一直WA,后面就看了Discuss,里面有个数组:ABCDEFDCBA,这个我输出ABCD,所以错了. 然后才知道自己写的后缀数组对这个回文子串有bug,然后就不知道怎么改了. 然后看题解,里面都是用RMQ先预处理任意两个后缀的最长公共前缀,因为不太知道这个,所以又看了一下午,嘛嘛-- 然后理解RMQ和后缀一起用的时候才发现其实这里不用RMQ也可以,只要特殊处理一下上面这个没过的例子就行了,哈哈--机智-- 不过那个国家集训队论文里面正解是用RMQ做的,自己还得会和RMQ一

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

1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 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» s

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

Ural 1297 Palindrome 【最长回文子串】

最长回文子串 相关资料: 1.暴力法 2.动态规划 3.中心扩展 4.Manacher法 http://blog.csdn.net/ywhorizen/article/details/6629268 http://blog.csdn.net/kangroger/article/details/37742639 在看后缀数组的时候碰到的这道题目 不过没用后缀数组写出来= = 用了一个很暴力的做法卡进了1 s Source Code: //#pragma comment(linker, "/STAC

【URAL 1297】Palindrome 最长回文子串

模板题,,,模板打错查了1h+QAQ #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1000003; int t1[N], t2[N], c[N], f[N][30]; void st(int *x, int *y, int *sa, int n, int m) { int i; for(i =

HDU 5371——Hotaru&#39;s problem——————【manacher处理回文】

Hotaru's problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1765    Accepted Submission(s): 635 Problem Description Hotaru Ichijou recently is addicated to math problems. Now she is playing

HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列,该子序列分为三部分,第一部分与第三部分相同,第一部分与第二部分对称,如果存在求最长的符合这种条件的序列. 思路:用Manacher算法来处理回文串的长度,记录下以每一个-1(Manacher算法的插入)为中心的最大回文串的长度.然后从最大的开始穷举,只要p[i]-1即能得出以数字为中心的最大回文串的长度,然后找到右边对应的'-1',判断p[i]是不是大于所穷举的长度,如果当前的满足三段,那么就跳出,继续