zoukankan      html  css  js  c++  java
  • Hdu5785-Interesting(回文串处理)

    Problem Description
    Alice get a string S. She thinks palindrome string is interesting. Now she wanna know how many three tuple (i,j,k) satisfy 1ij<klength(S) , S[i..j] and S[j+1..k] are all palindrome strings. It's easy for her. She wants to know the sum of i*k of all required three tuples. She can't solve it. So can you help her? The answer may be very large, please output the answer mod 1000000007.

    A palindrome string is a string that is same when the string is read from left to right as when the string is read from right to left.
     
    Input
    The input contains multiple test cases.

    Each test case contains one string. The length of string is between 1 and 1000000. String only contains lowercase letter.
     
    Output
    For each test case output the answer mod 1000000007.
     
    Sample Input
    aaa
    abc
     
    Sample Output
    14
    8

    题意: 找三元组(i,j,k) 使得[i,j]和[j+1,k]都是回文串。计算所有i*k的和模上1000000007.

    解析:先跑一边manacher.然后处理4个数组

    C[0][i]: 代表对于下标i的点,他所在的回文串(回文串在他右边)中心下标*2的和

    C[1][i]: 代表对于下标i的点,他所在的回文串(回文串在他左边)中心下标*2的和

    C[2][i]: 代表对于下标i的点,他所在的回文串个数(回文串在他右边)

    C[3][i]: :代表对于下标i的点,他所在的回文串个数(回文串在他左边)

    对于以x为左端点的回文串,那么它右边的所有k的和为C[0][x]-C[2][x]*x(想一想为甚么,得到的恰好是所有包含x为左端点的回文的长度),以

    x为右端点同理。还要注意奇偶性,我参照了别人的写法。

    代码: 

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int mod=1000000007;
    const int maxn=2000010;
    char org[maxn],S[maxn];
    int p[maxn];
    inline int manacher() //manacher实现部分
    {
        S[0]='$'; S[1]='#';
        int len=2;
        int L=strlen(org);
        for(int i=0;i<L;i++)
        {
            S[len++]=org[i];
            S[len++]='#';
        }
        S[len]='@';
        S[len+1]=0;
        int ri=0,id;
        for(int i=1;i<len;i++)
        {
            if(ri>i) p[i]=min(p[2*id-i],ri-i);
            else p[i]=1;
            while(S[i+p[i]]==S[i-p[i]]) p[i]++;
            if(i+p[i]>ri) { ri=i+p[i]; id=i; }
        }
        return len-1;
    }
    int C[4][maxn];
    void Modify(int k,int l,int r,int v) //修改
    {
        if(l>r) return;
        C[k][l]=(C[k][l]+v)%mod;  //l位置要加上v
        C[k][r+1]=(C[k][r+1]-v+mod)%mod; //r+1要减去v因为从l到r这一段是累加的,但是到r+1开始就要减掉了
    }
    int main()
    {
        while(scanf("%s",org)!=EOF)
        {
            int len=manacher();
            memset(C,0,sizeof(C));
            for(int i=len;i>=1;i--)
            {
                Modify(0,i-p[i]+1,i,i); 
                Modify(2,i-p[i]+1,i,1);
            }
            for(int i=1;i<=len;i++)
            {
                Modify(1,i,i+p[i]-1,i);
                Modify(3,i,i+p[i]-1,1);
            }
            for(int k=0;k<4;k++)
                for(int i=1;i<=len;i++) C[k][i]=(C[k][i]+C[k][i-1])%mod;
            int ans=0;
            for(int i=2;i<len-1;i+=2)
            {
                int a=i,b=i+2;
                int lsum=(C[0][b]-(LL)C[2][b]*(b/2)%mod+mod)%mod;
                int rsum=(C[1][a]-(LL)C[3][a]*(a/2)%mod+mod)%mod;
                ans=(ans+(LL)lsum*rsum%mod)%mod;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    AndroidStudio gradle配置
    Git中pull对比fetch和merge
    Knockout.js随手记(7)
    Knockout.js随手记(6)
    MVC自动绑定整数数组
    Knockout.js随手记(5)
    ASP.NET4.5Web API及非同步程序开发系列(3)
    Knockout.js随手记(4)
    ASP.NET4.5Web API及非同步程序开发系列(2)
    ASP.NET4.5Web API及非同步程序开发系列(1)
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5745654.html
Copyright © 2011-2022 走看看