zoukankan      html  css  js  c++  java
  • Best Reward---hdu3613(manacher 回文串)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613

    题意就是给你一个串s 然后求把s分成两部分之后的价值总和是多少,分开的串 如果是回文那么价值就是每个字母的价值之和,如果不是那么价值就是0;

    例如:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    abbadf

    那么可以分成abba 和df abba的价值是1+2+2+1=6,df不是回文串所以价值为0;总价值就是6;

    我们可以用数组L【i】R【i】来记录串的前缀长度为i的是否是回文串和后缀长度为i的是否是回文串;

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    const int N = 1e6+7;
    
    int v[26], sum[N], p[N];
    ///sum[i]代表s串中前i个字符的价值总和;
    ///p[i]代表以i为中心的回文串的半径(包含i本身);
    char s[N];
    bool L[N], R[N];
    ///L[i]表示前i个字符是否是回文串,R[i]表示长度为i的后缀是否为回文串;
    
    void Manacher(char s[], int n)
    {
        int Id = 0, mx = 0;
        for(int i=2; i<n; i++)
        {
            if(mx>i)
                p[i] = min(mx-i, p[Id*2-i]);
            else
                p[i] = 1;
            while(s[i+p[i]] == s[i-p[i]])
                p[i]++;
            if(mx < p[i]+i)
            {
                mx = p[i]+i;
                Id = i;
            }
    
            if(p[i] == i)
                L[p[i]-1] = true;
            if(p[i]+i == n)
                R[p[i]-1] = true;
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            memset(L, 0, sizeof(L));
            memset(R, 0, sizeof(R));
            memset(p, 0, sizeof(p));
            memset(sum, 0, sizeof(sum));
            for(int i=0; i<26; i++)
                scanf("%d", &v[i]);
            scanf("%s", s);
            int len = strlen(s);
            for(int i=1; i<=len; i++)
                sum[i] += sum[i-1] + v[s[i-1]-'a'];
            for(int i=len; i>=0; i--)
            {
                s[i+i+2] = s[i];
                s[i+i+1] = '#';
            }
            s[0]='$';
            Manacher(s, 2*len+2);
            int ans = 0;
            for(int i=1; i<len; i++)
            {
                int t=0;
                if(L[i])
                    t+=sum[i];
                if(R[len-i])
                    t+=sum[len]-sum[i];
                ans = max(ans, t);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    django笔记
    pandas dataframe的合并(append, merge, concat)
    pandas删除行删除列,增加行增加列
    github上值得关注的前端项目
    CSS布局奇淫技巧之--各种居中
    级联菜单
    鼠标移入移出改变透明度
    图片轮播特效
    图片放大镜效果
    css3多列布局
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4851179.html
Copyright © 2011-2022 走看看