zoukankan      html  css  js  c++  java
  • [codeforces] 17E Palisection

    原题

    题目要求相交的回文串对数,这显然非常难,但是要有一种正难则反的心态,求不出来相交的,求出来不相交的不就好了!
    对于每以位置i结尾的字符串,在他后面与他不相交的就是以这个位置为结尾的个数和以这个位置以后为开头的乘积。
    而答案就是总回文串个数sum*(sum-1)/2减去不相交个数

    提到回文串,我们会想到manacher,但是这求出来的是中心的回文串最长半径,怎么转换成结尾和开头的个数呢?

    对于已知位置i和以i为中心的回文串最长半径a[i],显然从i-a[i]到i都可以作为一个回文串的开头,i到a+a[i]都可以作为一个回文串的结尾,所以我们就会联想到差分!在转换过程中先把开头数组和结尾数组维护为查分,然后再还原即可。还原后要对开头数组维护一个后缀和,这样就可以O(n)了~!

    #include<cstdio>
    #include<algorithm>
    #define N 2000010
    #define mo 51123987
    using namespace std;
    long long n,l,a[2*N],f[2*N],g[2*N],ans,mxr,p,sum;
    char s[2*N];
    
    int main()
    {
        s[0]='@';
        scanf("%d",&l);
        getchar();
        for (int i=1;i<=l;i++)
        {
    	s[i*2-1]='#';
    	s[i*2]=getchar();
        }
        s[l*2+1]='#';
        s[l*2+2]='?';
        n=l*2+1;
        for (int i=1,q;i<=n;i++)
        {
    	if (mxr>i) q=min(mxr-i,a[p*2-i]);
    	else q=1;
    	while (s[i-q]==s[i+q]) q++;
    	a[i]=q;
    	sum+=(a[i]-1)/2;
    	if (i%2==0) sum++;
    	sum%=mo;
    	if (i+q>mxr) mxr=i+q,p=i;
        }
        sum=sum*(sum-1)/2;
        for (int i=2;i<=n;i+=2)
        {
    	f[i-a[i]+2]++;
    	f[i+2]--;
    	g[i]++;
    	g[i+a[i]]--;
        }
        for (int i=1;i<=n;i+=2)
        {
    	f[i-a[i]+2]++;
    	f[i+1]--;
    	g[i+1]++;
    	g[i+a[i]]--;
        }
        for (int i=2;i<=n;i+=2)
        {
    	f[i]+=f[i-2];
    	f[i]%=mo;
    	g[i]+=g[i-2];
    	g[i]%=mo;
        }
        f[n+1]=0;
        for (int i=n-1;i>=1;i-=2)
        {
    	f[i]+=f[i+2];
    	f[i]%=mo;
        }
        for (int i=2;i<=n;i+=2)
        {
      	sum-=g[i]*f[i+2]%mo;
    	sum=(sum+mo)%mo;
        }
        printf("%lld
    ",(sum%mo+mo)%mo);
        return 0;
    }
    
    
  • 相关阅读:
    2013第38周日Java文件上传下载收集思考
    2013年第38周六这一刻,行动
    2013年9月20日突然的焦虑
    2013中秋
    2013第38周三
    2013年第38周二
    2013第38周一电话开会邮件
    for循环中一个不容小觑的问题
    NPOI 创建Excel,数据读取与写入
    linux下mysql数据的导出和导入
  • 原文地址:https://www.cnblogs.com/mrha/p/7879760.html
Copyright © 2011-2022 走看看