zoukankan      html  css  js  c++  java
  • Manacher HDOJ 5371 Hotaru's problem

    题目传送门

     1 /*
     2     题意:求形如(2 3 4) (4 3 2) (2 3 4)的最长长度,即两个重叠一半的回文串
     3     Manacher:比赛看到这题还以为套个模板就行了,因为BC上有道类似的题,自己又学过Manacher算法,结果入坑WA到死
     4         开始写的是判断是否 p[i]-1 <= p[i+p[i]-1]-1,但是没有想到这种情况:5 (5 1) (1 5) (5 1) 1
     5         单靠最长回文半径是不行的,看了网上的解题报告知道,要从极端位置往回挪才行
     6         给我的教训是只会套模板是没用的,要灵活的使用该算法。另外max() 函数似乎很费时间
     7   详细解释
     8 */
     9 /************************************************
    10 * Author        :Running_Time
    11 * Created Time  :2015-8-11 12:52:49
    12 * File Name     :C.cpp
    13  ************************************************/
    14 
    15 #include <cstdio>
    16 #include <algorithm>
    17 #include <iostream>
    18 #include <sstream>
    19 #include <cstring>
    20 #include <cmath>
    21 #include <string>
    22 #include <vector>
    23 #include <queue>
    24 #include <deque>
    25 #include <stack>
    26 #include <list>
    27 #include <map>
    28 #include <set>
    29 #include <bitset>
    30 #include <cstdlib>
    31 #include <ctime>
    32 using namespace std;
    33 
    34 #define lson l, mid, rt << 1
    35 #define rson mid + 1, r, rt << 1 | 1
    36 typedef long long ll;
    37 const int MAXN = 1e5 + 10;
    38 const int INF = 0x3f3f3f3f;
    39 const ll INFF = 0x7fffffff;
    40 const int MOD = 1e9 + 7;
    41 int a[MAXN*2], p[MAXN*2];
    42 int n;
    43 
    44 int Manacher(void)    {
    45     a[n] = INF + 2;
    46     for (int i=n; i>=0; --i)    {
    47         a[i*2+2] = a[i];    a[i*2+1] = INF;
    48     }
    49     a[0] = INF + 1;    n = n * 2 + 2;
    50     int id = 0;    p[0] = 1;
    51     for (int i=2; i<n; ++i)    {
    52         if (id + p[id] > i)    p[i] = min (p[2*id-i], id + p[id] - i);
    53         else    p[i] = 1;
    54         while (a[i-p[i]] == a[i+p[i]])    p[i]++;
    55         if (id + p[id] < i + p[i])    id = i;
    56     }
    57 
    58     int mx = 0;
    59     for (int i=3; i<=n-2; i+=2)    {
    60         if (p[i] - 1 > mx)    {
    61             int c = p[i] - 1;
    62             while (c > mx && p[i+c] < c)    c--;
    63             mx = mx > c ? mx : c;
    64         }
    65     }
    66 
    67     return mx / 2 * 3;
    68 }
    69 
    70 int main(void)    {        //HDOJ 5371 Hotaru's problem
    71     int T, cas = 0;    scanf ("%d", &T);
    72     while (T--)    {
    73         scanf ("%d", &n);
    74         for (int i=0; i<n; ++i)    scanf ("%d", &a[i]);
    75         printf ("Case #%d: %d
    ", ++cas, Manacher ());
    76     }
    77 
    78     return 0;
    79 }
    编译人生,运行世界!
  • 相关阅读:
    Encryption (hard) CodeForces
    cf 1163D Mysterious Code (字符串, dp)
    AC日记——大整数的因子 openjudge 1.6 13
    AC日记——计算2的N次方 openjudge 1.6 12
    Ac日记——大整数减法 openjudge 1.6 11
    AC日记——大整数加法 openjudge 1.6 10
    AC日记——组合数问题 落谷 P2822 noip2016day2T1
    AC日记——向量点积计算 openjudge 1.6 09
    AC日记——石头剪刀布 openjudge 1.6 08
    AC日记——有趣的跳跃 openjudge 1.6 07
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4723498.html
Copyright © 2011-2022 走看看