• POJ


    题意

    给n个字符串,两两拼接,问拼接后的(n imes n)个字符串中有多少个回文串。

    分析

    将所有正串插入字典树中,马拉车跑出所有串哪些前缀和后缀为回文串,记录位置,用反串去字典树中查询,两字符串拼成回文串有三种情况:

    • 未匹配完,反串后缀是回文串。

    • 匹配结束,正串后缀是回文串。

    • 匹配结束,正串等于反串。

    字典树中维护当前位置有多少正串和当前位置有多少后缀为回文串的正串。

    Code

    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    #define ll long long
    using namespace std;
    const int inf=1e9;
    const int mod=1e9+7;
    const int maxn=2e6+10;
    int p[maxn*2],f[2][maxn],len[maxn],sum[2][maxn];
    char s[maxn],t[maxn*2];
    int son[maxn][26],tot;
    ll ans;
    void ins(int dl,int dr){
        int rt=0;
        for(int i=dl;i<=dr;i++){
            if(f[1][i]) sum[1][rt]++;
            if(!son[rt][s[i]-'a']) son[rt][s[i]-'a']=++tot;
            rt=son[rt][s[i]-'a'];
            if(i==dr) sum[0][rt]++;
        }
    }
    void qy(int dl,int dr){
        int rt=0;
        for(int i=dr;i>=dl;i--){
            if(f[0][i]) ans+=sum[0][rt];
            if(!son[rt][s[i]-'a']) return;
            rt=son[rt][s[i]-'a'];
            if(i==dl) ans+=sum[1][rt]+sum[0][rt];
        }
    }
    int mlc(int dl,int dr){
        int m=0,p0=1;p[1]=1;t[++m]='#';
        for(int i=dl;i<=dr;i++){
            t[++m]=s[i];
            t[++m]='#';
        }
        for(int i=2;i<=m;i++){
            int j=min(p[p0]+p0-i,p[2*p0-i]);
            if(i+j<p[p0]+p0){
                p[i]=j;
            }else{
                while(i-j>=1&&i+j<=m&&t[i-j]==t[i+j]) ++j;
                p[i]=j;p0=i;
            }
        }
        for(int i=dl;i<dr;i++){
            if(p[i-dl+2]-1==i-dl+1) f[0][i]=1;
            if(p[dr-2*dl+i+3]-1==dr-i) f[1][i+1]=1;
        }
    }
    int main(){
    	//ios::sync_with_stdio(false);
    	//freopen("in","r",stdin);
    	int n;
    	scanf("%d",&n);int l=1;
    	for(int i=1,m;i<=n;i++){
    		scanf("%d%s",&len[i],s+l);
            mlc(l,l+len[i]-1);
            ins(l,l+len[i]-1);
            l+=len[i];
    	}l=1;
    	for(int i=1;i<=n;i++){
            qy(l,l+len[i]-1);
            l+=len[i];
    	}
    	cout<<ans<<'
    ';
    	return 0;
    }
    
  • 相关阅读:
    《仔仔细细分析Ext》 第N2章 GridPanel的小难点 第一节 每条数据后面跟随几个操作按钮
    TextField输入验证
    Ext.FormPanel 及控件横排显示
    备份
    重写
    this关键字
    TestCircle程序分析
    java方法重载
    static关键字
    super关键字
  • 原文地址:https://www.cnblogs.com/xyq0220/p/11511779.html
Copyright © 2020-2023  润新知