zoukankan      html  css  js  c++  java
  • BZOJ 4480 [JSOI2013] 快乐的jyy

    思路

    两个字符串都插入回文自动机中(每次重置last)
    最后统计两个right集合的大小就好了

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int Nodecnt,cnt[50100][2],trans[50100][26],fail[50100],len[50100],s[2][50100],last,n;
    long long ans=0;
    char S[50100];
    int New_state(int _len){
        len[Nodecnt]=_len;
        return Nodecnt++;
    }
    int getfail(int p,int n,int which){
        while(s[which][n-len[p]-1]!=s[which][n])
            p=fail[p];
        return p;
    }
    void add_len(int n,int which){
        int cur=getfail(last,n,which);
        if(!trans[cur][s[which][n]]){
            int t=New_state(len[cur]+2);
            fail[t]=trans[getfail(fail[cur],n,which)][s[which][n]];
            trans[cur][s[which][n]]=t;
        }
        cnt[trans[cur][s[which][n]]][which]++;
        last=trans[cur][s[which][n]];
    }
    int main(){
        s[0][0]=-1;
        s[1][0]=-1;
        New_state(0);
        New_state(-1);
        fail[0]=1;
        last=0;
        scanf("%s",S+1);
        n=strlen(S+1);
        for(int i=1;i<=n;i++){
            S[i]-='A';
            s[0][i]=S[i];
            add_len(i,0);
        }
        last=0;
        scanf("%s",S+1);
        n=strlen(S+1);
        for(int i=1;i<=n;i++){
            S[i]-='A';
            s[1][i]=S[i];
            add_len(i,1);
        }
        for(int i=Nodecnt-1;i>=0;i--)
            cnt[fail[i]][0]+=cnt[i][0],cnt[fail[i]][1]+=cnt[i][1];
        for(int i=2;i<Nodecnt;i++)
            ans=(1LL*ans+1LL*cnt[i][0]*cnt[i][1]);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    无法加载模块 TP3.2
    always_populate_raw_post_data
    关于(void**)及其相关的理解
    面向对象设计原则
    数据对齐总结
    C++ POD类型
    do..while(false)的用法总结
    c++为什么定义了析构函数的类的operator new[]传入的参数会多4字节?
    C++ new new[]详解
    【转】C内存操作函数
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10644525.html
Copyright © 2011-2022 走看看