• HDU4513吉哥系列故事――完美队形II(manacher算法)


    这个比最长回文子串就多了一个条件,就是回文字串(这里相当于人的高度)由两端向中间递增。

    才刚刚看了看manacher,在用模板A了一道题后,还没有完全理解manacher,然后就准备把这道题也直接带模板的。

    却发现这个递增的要求实在是麻烦,然后实在是没办法了,就把manacher算法拆开了,写两遍,按照子串的中间是一个数还是两个数来写。

    其他的什么地方都没改,只是扩展的时候把题目要求的条件加上就好了。

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FOPENIN(IN) freopen(IN, "r", stdin)
    23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
    24 
    25 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    26 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    27 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    28 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    31 
    32 //typedef __int64 LL;
    33 typedef long long LL;
    34 const int MAXN = 4000000+10;
    35 const int MAXM = 2000010;
    36 const double eps = 1e-12;
    37 
    38 int high[MAXN];
    39 int rad[MAXN];
    40 int T, N;
    41 
    42 int manacherOdd()
    43 {
    44     mem0(rad);
    45     for(int i=1,j=0,k;i<=N;)
    46     {
    47         while (high[i-j-1]==high[i+j+1] && high[i-j]>=high[i-j-1]) j++;  //扫描得出rad值
    48         rad[i]=j;
    49         for (k=1; k<=j && rad[i-k]!=rad[i]-k; k++) rad[i+k]=min(rad[i-k],rad[i]-k);  //k指针扫描
    50         i+=k;  //i跳到下一个需要计算rad值的位置
    51         j=max(j-k,0);  //更新下一个rad值的初始值
    52         //printf("%d
    ", i);
    53     }
    54     int ans = 0;
    55     for(int i=1;i<=N;i++)
    56     {
    57         ans = max(ans, rad[i]*2+1);
    58     }
    59     return ans;
    60 }
    61 
    62 int manacherEven()
    63 {
    64     mem0(rad);
    65     int j = 0, k;
    66     for(int i=1;i<N;)
    67         if(high[i]==high[i+1])
    68         {
    69             while(high[i-j-1] == high[i+j+2] && high[i-j]>=high[i-j-1]) j++;
    70             rad[i] = j+1;
    71             for(k=1;k<=j && rad[i-k]!=rad[i]-k; k++) rad[i+k]=min(rad[i-k],rad[i]-k);
    72             i += k;
    73             j = max(j-k, 0);
    74             //printf("%d
    ", i);
    75         }
    76         else i++;
    77     int ans = 0;
    78     for(int i=1;i<=N;i++)
    79     {
    80         ans = max(ans, rad[i]*2);
    81     }
    82     return ans;
    83 }
    84 
    85 int main()
    86 {
    87     while(~scanf("%d", &T))while(T--)
    88     {
    89         scanf("%d", &N);
    90         for(int i=1;i<=N;i++) scanf("%d", &high[i]);
    91         high[0] = high[N+1] = INF;
    92         int ans = max( manacherOdd(), manacherEven());
    93         printf("%d
    ", ans);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    iot 表 主键索引叶子块包含了表所有数据
    iot 表索引dump《2》
    iot 表索引dump《2》
    heap表和iot表排序规则不同
    heap表和iot表排序规则不同
    ActiveMQ学习总结(4)——业界消息队列简介
    主宰全球的10大算法
    主宰全球的10大算法
    主宰全球的10大算法
    SVN学习总结(1)——SVN简介及入门使用
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3622914.html
Copyright © 2020-2023  润新知