【NOI2016】优秀的拆分(95分)

来源:互联网 发布:女人下没有用知专卖店 编辑:程序博客网 时间:2024/05/17 17:16

uoj 传送门

题目大意:给出一串字符串,求它的子串中形如AABB的方案个数。

90% len<=2000 ,O(n^2) 的做法可以过。
100% len<=30000, 蒟蒻不会啦。

O(n^2)的做法:
枚举中间点,求出两边形如AA的个数,相乘加入答案中。

#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring> #define LL long long#define MOD 1000000009#define base 163#define M 30009using namespace std;int T,len;LL Hash[M],P[M],ans;char a[2009];LL get_hash(int L,int R){    return (Hash[R]-Hash[L-1]*P[R-L+1]%MOD+MOD)%MOD;}int main(){    P[0]=1;    for(int i=1;i<=2001;i++) P[i]=P[i-1]*base%MOD;    scanf("%d",&T);    while(T--)    {        //gets(a+1);        cin>>a+1;        len=strlen(a+1);        for(int i=1;i<=len;i++) Hash[i]=(Hash[i-1]*base+a[i]-'a')%MOD;        ans=0;        for(int i=2;i<=len-1;i++)        {            int L=0,R=0;            for(int j=i/2;j;j--)            {                if(get_hash(i-j+1,i)==get_hash(i-2*j+1,i-j)) L++;            }            for(int j=(len-i)/2;j;j--)            {                if(get_hash(i+1,i+j)==get_hash(i+j+1,i+2*j)) R++;            }            ans+=L*R;        }        printf("%lld\n",ans);    }    return 0;}
原创粉丝点击