zoukankan      html  css  js  c++  java
  • BZOJ 4650: [Noi2016]优秀的拆分

    题意:给你一个串,让你找出AABB型的子串有多少种,A可以为一个字符串,但A≠B

    思路:我觉得这篇讲的很清楚(传送门),我觉得这个题只有在lcp的那个地方不是很容易想到,从来没想过lcp还可以这么用,代码是搬运claris小姐姐

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=80005;
    char s[maxn];
    int T,n,Log[maxn],l,r,f[maxn],g[maxn];
    LL ans;
    /**
    在使用后缀数组时要先进行倍增预处理,调用init_suffix
    s为字符串
    sa为后缀数组,记录排序后的后缀数组的位置
    rk为记录以i开始的后缀在后缀数组中的位置
    height为高度数组,表示排序后相邻的两个后缀的公共前缀
    lcp函数可以查两个位置的lcp公共长度
    */
    void init_suffix()
    {
        for(int i=2;i<maxn;i++)Log[i]=Log[i>>1]+1;
    }
    struct SuffixArray
    {
        char s[maxn];
        int sa[maxn],rk[maxn],height[maxn],tmp[maxn],cnt[maxn],f[15][maxn],len;
        inline void init()
        {
            for(int i=0;i<len*2+5;i++)s[i]=0;
        }
        inline void suffix(int m)
        {
            int i,j,k,len1=len+1;;
            for(i=0;i<len1*2+5;i++)rk[i]=sa[i]=height[i]=tmp[i]=0;
            for(i=0;i<m;i++)cnt[i]=0;
            for(i=0;i<len1;i++)cnt[rk[i]=s[i]]++;
            for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
            for(i=0;i<len1;i++)sa[--cnt[rk[i]]]=i;
            for(k=1;k<=len1;k<<=1){
                for(i=0;i<len1;i++){
                    j=sa[i]-k;
                    if(j<0)j+=len1;
                    tmp[cnt[rk[j]]++]=j;
                }
                sa[tmp[cnt[0]=0]]=j=0;
                for(i=1;i<len1;i++){
                    if(rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k])cnt[++j]=i;
                    sa[tmp[i]]=j;
                }
                memcpy(rk,sa,len1*sizeof(int));
                memcpy(sa,tmp,len1*sizeof(int));
                if(j>=len1-1)break;
            }
            for(j=rk[height[i=k=0]=0];i<len1-1;i++,k++){
                while(~k&&s[i]!=s[sa[j-1]+k])height[j]=k--,j=rk[sa[j]+1];
            }
        }
        inline void build()
        {
            int i,j;
            for(i=1;i<=len;i++)f[0][i]=height[i];
            for(j=1;j<15;j++){
                for(i=1;i+(1<<j-1)<=n;i++){
                    f[j][i]=min(f[j-1][i],f[j-1][i+(1<<j-1)]);
                }
            }
        }
        inline int ask(int x,int y)
        {
            int k=Log[y-x+1];
            return min(f[k][x],f[k][y-(1<<k)+1]);
        }
        inline int lcp(int x,int y)
        {
            x=rk[x],y=rk[y];
            if(x>y)swap(x,y);
            return ask(x+1,y);
        }
    }A,B;
    
    inline int lcp(int x,int y){return A.lcp(x-1,y-1);}
    inline int lcs(int x,int y){return B.lcp(n-x,n-y);}
    int main()
    {
        init_suffix();
        scanf("%d",&T);
        while(T--){
            scanf("%s",s);
            n=strlen(s);
            A.len=B.len=n;
            A.init();B.init();
            for(int i=0;i<n;i++)A.s[i]=B.s[n-i-1]=s[i];
            A.suffix(128);
            A.build();
            B.suffix(128);
            B.build();
            for(int i=1;i<=n;i++)f[i]=g[i]=0;
            for(int i=1;i+i<=n;i++){
                for(int j=i+i;j<=n;j+=i){
                    if(s[j-1]==s[j-i-1]){
                        l=j-lcs(j,j-i)+1,r=j+lcp(j,j-i)-1;
                        l=max(l+i-1,j),r=min(r,j+i-1);
                        if(l<=r){
                            f[l]++,f[r+1]--;
                            g[l-i-i+1]++,g[r+1-i-i+1]--;
                        }
                    }
                }
            }
            for(int i=1;i<=n;i++)f[i]+=f[i-1],g[i]+=g[i-1];
            ans=0;
            for(int i=1;i<n;i++)ans+=f[i]*g[i+1];
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    mina2中的session
    mina2的processor
    Spring Cloud 各组件调优参数
    可重入锁
    微服务架构的基础框架选择:Spring Cloud还是Dubbo?
    服务注册发现consul之五:Consul移除失效服务的正确姿势
    Spring Cloud构建微服务架构(七)消息总线
    springboot+swagger
    Spring Cloud config之二:Spring cloud config Server源码分析
    Spring Cloud config之一:分布式配置中心config server介绍
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9464231.html
Copyright © 2011-2022 走看看