题目

源地址:

http://codeforces.com/problemset/problem/7/D

理解

被引入的新概念吓到了= =,其实这道题就是一个求最大回文串的问题。 不过按照这个数据量,每一次都进行strcmp肯定不现实,所以我们需要一个好的字符串hash(的板子)。预处理之后,分别计算前缀和后缀的hash值。如果hash值相等,说明前缀和后缀相同,它们的度数就是长度/2再加上一。然后结果就是度数的和。

字符串hash的时候那个素数开大一点比较好,不用去处理hash冲突,23333。

代码


#define MAXN 5000000+10
#define MOD  1000000007
#define BIG  10000009

char a[MAXN];
ll n,l[MAXN],r[MAXN],dp[MAXN];
ll i,j,len;
ll ans = 0;

void init()
{
    scanf("%s", a);
    dp[0]=0;
    for(i=0; a[i]; i++)
    {
        if('0'<=a[i]&&a[i]<='9')
            a[i] = a[i]-'0';
        else if('a'<=a[i]&&a[i]<='z')
            a[i] = a[i]-'a'+10;
        else
            a[i] = a[i]-'A'+36;
    }
}

int main(int argc, char const *argv[])
{
    init();
    len = i;
    l[0] = 0;
    ll tmp = 1;
    for(i=1; i<=len; i++)
    {
        l[i] = (l[i-1]+a[i-1]*tmp)%MOD;
        tmp = (tmp*BIG)%MOD;
    }

    r[len+1] = 0;
    for(i=1; i<=len; i++)
    {
        r[i] = (r[i-1]*BIG+a[i-1])%MOD;
    }

    ans=0;
    for(i=1; i<=len; i++)
    {
        if(l[i]==r[i])
        {
            dp[i] = dp[i>>1]+1;
            ans += dp[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

更新日志

  • 2014年11月16日 已AC。