现在的位置: 首页 > 综合 > 正文

hdu4632

2013年10月06日 ⁄ 综合 ⁄ 共 1483字 ⁄ 字号 评论关闭

/*
分析:
    (找规律+递推) && (线段树 || 树状数组),非区间dp方法。
    以后都不准备再贴水题了,不过这题我比赛时想到的方法和解题报告的方法不一样,所
以贴下。。

    1. 经过观察,发现性质:对于str[i]==str[j]  && i<j,那么所有首位为a、末位为b、且满足
(i<a && a<=b && b<j)的回文序列,一定可以在两端加上str[i]和str[j]后,构成一个新的回
文序列,并且这个回文序列的首元素为str[i]、尾元素为str[j];
    2. 维护两个数组,ans[N]和cnt[N],ans[i]表示以元素i为首位的回文序列的数量、cnt[i]表
示以元素i结尾的回文序列的数量;
    3. 逆向遍历str(正向也行),初始化ans[i]=1,cnt[i]=1,代表自己单独为一个序列;同
时用指针j,从str尾向前遍历while(i<j),当str[i]==str[j]的时候,进行如下操作:
        (1)ans[i]++,cnt[j]++,(代表i和j单独构成一个序列);
        (2)统计sum=所有cnt[k]的和,k满足(i<k && k<j),然后ans[i]+=sum,cnt[i]+=sum;
        
    最后统计所有的ans的SUM,既为所求。
    对于3.(2),需要用树状数组或者线段树快速求和。
    
源自-------------------------------------Ice_Crazy

                                                                    2013-08-02
*/

#include"iostream"
#include"cstdio"
#include"cstring"
using namespace std;
const int N=1006;
const int mod=10007;


int n,lowbit[N];
__int64 C[N],ans[N];
char str[N];

void update(int k,int dir)
{
    while(0<k && k<=n)
    {
        C[k]=(C[k]+dir)%mod;
        k+=lowbit[k];
    }
}
int sum(int k)
{
    __int64 p=0;
    while(0<k && k<=n)
    {
        p=(p+C[k])%mod;
        k-=lowbit[k];
    }
    return p;
}
int main()
{
    int T,Case;
    int i,l;
    __int64 a,b,t;
    __int64 hehe;
    for(i=1;i<=1000;i++)    lowbit[i]=i&(-i);
    cin>>T;
    for(Case=1;Case<=T;Case++)
    {
        hehe=0;
        scanf("%s",str+1);

        memset(C,0,sizeof(C));
        memset(ans,0,sizeof(ans));
        for(n=1;str[n];n++);
        n--;

        for(i=n;i>=1;i--)
        {
            ans[i]=1;
            update(i,1);
            for(l=n;l>i;l--)
            {
                if(str[l]==str[i])
                {
                    a=sum(i);
                    b=sum(l-1);
                    t=(b-a)%mod;
                    while(t<0)    t+=mod;
                    ans[i]=(ans[i]+1+t)%mod;
                    update(l,1+t);
                }
            }
        }

        hehe=0;
        for(i=1;i<=n;i++)    hehe=(hehe+ans[i])%mod;
        printf("Case %d: %I64d\n",Case,hehe);
    }
    return 0;
}

抱歉!评论已关闭.