manacher算法

https://blog.csdn.net/qq_16554583/article/details/79763296

https://blog.csdn.net/qq_41923622/article/details/80109897

https://blog.csdn.net/pk__pk/article/details/79566540 这个好懂

最长回文

 HDU - 3068 

 

//马拉车算法基础模板,求最长的回文半径。
//其中init函数是把原来的字符串每个字母中间插入一个串里没有出现过的字符,其中这个字符从1开始,0的位置也用一个没出现过的字符代替。
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxm = 3e5;
char s[maxm], str[maxm];
int len1, len2, p[maxm], ans;

void init() {
    str[0] = '*';
    str[1] = '#';
    for(int i = 0; i < len1; i++) {
        str[2 * i + 2] = s[i];
        str[2 * i + 3] = '#';
    }
    len2 = len1 * 2 + 2;
    str[len2] = '&';
}
void manacher() {
    int id = 0, mx = 0;
    for(int i = 1; i < len2; i++) {
        if(mx > i) p[i] = min(p[2 * id - i], mx - i);
        else p[i] = 1;
        for(; str[i + p[i] ] == str[i - p[i] ]; p[i]++);
        if(p[i] + i > mx) {
            mx = p[i] + i;
            id = i;
        }
    }
}

int main() {
    while(~scanf("%s", s)) {
        len1 = strlen(s);
        init();
        manacher();
        ans = 0;
        for(int i = 0; i < len2; i++) {
            ans = max(ans, p[i]);
        }
        printf("%d\n", ans - 1);
    }

    return 0;
}

 

 

C - Best Reward

 HDU - 3613 

https://blog.csdn.net/deerly_/article/details/79976504

https://blog.csdn.net/ummmmm/article/details/82462464

 

https://vjudge.net/contest/300092#problem/G

马拉车升级

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

const int MAXN = 250;
char mmp[MAXN + 5][MAXN + 5];
int a[MAXN<<1 + 5][26], tot[MAXN<<1 + 5];
int n,m;
LL ans;
bool cmp(int x, int y)
{
    if( tot[x] > 1 || tot[y] > 1 )
        return false;
    for(int i=0;i<26;i++)
    {
        if( a[x][i]!= a[y][i] )
        {
            return false;
        }
    }
    return true;
}

LL p[MAXN*2+5];
int manacher()
{
    int i;
    int len=n;
    len++;len<<=1;
    LL ret=0,mx=0,id=0;
    for(i=1;i<len;i++)
    {
        if(mx>i)p[i]=min(p[id*2-i],mx-i);
        else p[i]=1;
        int o=i;
        while(i-p[i]>0&&i+p[i]<len&&cmp(i-p[i],i+p[i]))
        {
            p[i]++;o++;
        }
        if(tot[i]>1)p[i]=1;
        if(mx<p[i]+i) mx=p[i]+i,id=i;
        ret=max(ret,p[i]);
        ans+=(p[i])/2;
    }
    return ret-1;
}


int main()
{
    scanf("%d%d", &n, &m);
    for(int i=0;i<n;i++) scanf("%s", mmp[i]);

    for(int i=0;i<m;i++) {
        for(int j=0;j<n;j++) {
            for(int k=0;k<26;k++) {
                a[(j+1)<<1][k]=tot[(j+1)<<1]=0;
            }
        }
        for(int j=i;j<m;j++)
        {
            for(int k=0;k<n;k++)
            {
                if(a[(k+1)<<1][mmp[k][j]-'a']&1) tot[(k+1)<<1]--;
                else tot[(k+1)<<1]++;
                a[(k+1)<<1][mmp[k][j]-'a']++;
            }
            manacher();
        }
    }
    printf("%lld\n", ans);
}

 

posted @ 2019-02-27 21:46  downrainsun  阅读(142)  评论(0编辑  收藏  举报