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

    求出一个连续子序列,这个子序列由三部分ABC构成,其中AB是回文串,A和C相同,也就是BC也是回文串。

    求这样一个最长的子序列。

    Manacher算法是在所有两个相邻数字之间插入一个特殊的数字,比如-1,

    Manacher算法跑完之后,就计算出每个数字为中心的回文子序列的最大长度

    由题意可以知道,AB和BC必然是长度为偶数的回文串。所以我们枚举回文串的中心就枚举相邻两个数字之间的缝隙,也就是那些-1

    把AB中间的间隙叫做左中心i,BC之间的间隙叫做右中心j,那么如果两个中心的范围能够互相覆盖,那么就找到一个符合条件的连续子序列。

    做法就是枚举左中心i,在左中心的范围内枚举右中心j,然后维护一个最大值即可。

    在枚举j的时候不要直接从[i+1, i + p[i] - 1]枚举,会超时的。

    比如说我们维护的最大值是ans,那么直接从 i + ans 开始枚举,因为之前的区间即使找到合法子序列也并不能更新这个最大值。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 100000 + 10;
     8 
     9 int n, tot;
    10 int a[maxn], b[maxn * 2];
    11 
    12 int p[maxn * 2];
    13 
    14 void Manacher()
    15 {
    16     int id, mx = 0;
    17     p[0] = 0;
    18     for(int i = 1; i < tot; i++)
    19     {
    20         if(mx > i) p[i] = min(p[id * 2 - i], mx - i);
    21         else p[i] = 1;
    22         while(b[i + p[i]] == b[i - p[i]]) p[i]++;
    23         if(i + p[i] > mx) { mx = i + p[i]; id = i; }
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     int T; scanf("%d", &T);
    30     for(int kase = 1; kase <= T; kase++)
    31     {
    32         scanf("%d", &n);
    33         for(int i = 0; i < n; i++) scanf("%d", a + i);
    34 
    35         b[0] = -2, b[1] = -1;
    36         tot = 2;
    37         for(int i = 0; i < n; i++)
    38         {
    39             b[tot++] = a[i];
    40             b[tot++] = -1;
    41         }
    42 
    43         Manacher();
    44 
    45         int ans = 1;
    46         for(int i = 3; i < tot; i += 2)
    47         {
    48             for(int j = ans; j <= p[i]; j += 2)
    49                 if(p[i + j - 1] >= j) ans = j;
    50         }
    51 
    52         ans = ans / 2 * 3;
    53         printf("Case #%d: %d
    ", kase, ans);
    54     }
    55 
    56     return 0;
    57 }
    代码君
  • 相关阅读:
    PostgreSQL数据库
    phpcms网站搬家 至 服务器 完整并且详细过程
    phpcms网页替换验证码功能 及 搜索功能
    用phpcms切换中英文网页的方法(不用解析二级域名)、phpcms完成pc和手机端切换(同一域名)
    php判断手机段登录,以及phpcms手机PC双模板调用
    php 手动搭建环境
    phpcms内容页替换
    phpcms列表页替换
    phpcms首页替换
    phpcms栏目点击选中
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4732720.html
Copyright © 2011-2022 走看看