• HDU5384-Hotaru's problem-Manacher


    找出紧挨的三个回文串,例如abccbaabc ,形如ABA格式,其中AB为回文串。计算最长的长度。

    首先用Manacher处理回文半径。然后就是找到两个点,都是偶数的回文串,并且共享了中间一段。

    之后拿set搞一下就可以了= =

     1 #include <set>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 
     7 using namespace std;
     8 
     9 const int maxn = 1e5+10;
    10 int Ma[maxn<<2],Mp[maxn<<2];
    11 set <int> pos;
    12 
    13 struct node{
    14     int mp,p;
    15     node(){}
    16     bool operator < (const node &rhs) const
    17     {
    18         if(mp == rhs.mp) return p > rhs.p;
    19         else return mp < rhs.mp;
    20     }
    21 };
    22 
    23 priority_queue<node> pq;
    24 void Manacher(int s[],int len)
    25 {
    26     int l = 0;
    27     Ma[l++] = '$';
    28     Ma[l++] = '#';
    29     for(int i=0;i<len;i++)
    30     {
    31         Ma[l++] = s[i];
    32         Ma[l++] = '#';
    33     }
    34     Ma[l] = 0;
    35     int mx = 0,id = 0;
    36     for(int i=0;i<l;i++)
    37     {
    38         Mp[i] = mx > i? min(Mp[2*id-i],mx-i) : 1;
    39         while(Ma[i + Mp[i]] == Ma[i-Mp[i]]) Mp[i]++;
    40         if(Mp[i] + i > mx)
    41         {
    42             mx = Mp[i] + i;
    43             id = i;
    44         }
    45     }
    46 }
    47 
    48 int T,N;
    49 int save[maxn];
    50 int main()
    51 {
    52     scanf("%d",&T);
    53     int cas = 0;
    54     while(T--)
    55     {
    56         scanf("%d",&N);
    57         for(int i=0;i<N;i++) scanf("%d",&save[i]);
    58         Manacher(save,N);
    59         int ans = 0;
    60         node tmp;
    61         while(!pq.empty()) pq.pop();
    62         pos.clear();
    63         for(int i=0;i<2*N+1;i++)
    64         {
    65             if(Ma[i] == '#' && Mp[i] > 1)
    66             {
    67                 tmp.mp = Mp[i];
    68                 tmp.p = i;
    69                 pq.push(tmp);
    70             }
    71         }
    72         int cnt = 0;
    73         //for(int i=0;i<2*N+1;i++) printf("%d	",i); puts("");
    74         //for(int i=0;i<2*N+1;i++) printf("%c	",Ma[i]=='#'?'#':Ma[i]+'0'); puts("");
    75         //for(int i=0;i<2*N+1;i++) printf("%d	",Mp[i]); puts("");
    76         while(!pq.empty())
    77         {
    78             tmp = pq.top(); pq.pop();
    79             int cur = tmp.p,mp = tmp.mp;
    80             //printf("cur:%d mp:%d
    ",cur,mp);
    81             int tmp_pos = 0;
    82             if(cnt)
    83             {
    84                 auto it = pos.lower_bound(cur - (mp-1) );
    85 
    86                 //printf("L:%d ",*it);
    87                 if(it != pos.end() && *it >= cur-(mp-1)) ans = max(ans,cur-*it);
    88 
    89                 it = pos.lower_bound(cur + (mp-1) ); it--;
    90                 //printf("R:%d
    ",*it);
    91                 if(it != pos.end() && *it <= cur+(mp-1)) ans = max(ans,*it-cur);
    92             }
    93             pos.insert(cur);
    94             cnt++;
    95         }
    96         printf("Case #%d: %d
    ",++cas,ans/2*3);
    97     }
    98 }
  • 相关阅读:
    P3224 [HNOI2012]永无乡(平衡树合并)
    jquery的队列问题
    值得以后看的东西
    js的>>>
    js的set和get
    js数组的操作方法
    中文冒号检查了两个小时
    setintervalue传参数的三种方法
    js轮训
    npm全局安装
  • 原文地址:https://www.cnblogs.com/helica/p/5750738.html
Copyright © 2020-2023  润新知