zoukankan      html  css  js  c++  java
  • UVALive

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/113725

    Repeated Substrings

    Time Limit: 3000MS

    样例

    sample input
    3
    aabaab
    aaaaa
    AaAaA

    sample output
    5
    4
    5

    题意

    求出现过两次以上的不同子串有多少种。

    题解

    用后缀数组求出height[]数组,然后扫一遍,发现height[i]-height[i-1]>=0;就ans+=height[i]-height[i-1]。

    代码

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    
    //start----------------------------------------------------------------------
    
    const int maxn=1e5+10; 
    
    struct SuffixArray{
        char s[maxn];
        int sa[maxn],t[maxn],t2[maxn],c[maxn];
        int n,m;
        void init(int n,int m){
            this->n=n;
            this->m=m;
        }
        void build_sa(){
            int i,*x=t,*y=t2;
            for(i=0;i<m;i++) c[i]=0;
            for(i=0;i<n;i++) c[x[i]=s[i]]++;
            for(i=1;i<m;i++) c[i]+=c[i-1];
            for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
            for(int k=1;k<=n;k<<=1){
                int p=0;
                for(i=n-k;i<n;i++) y[p++]=i;
                for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
    //            for(i=0;i<n;i++) y[p++]=(sa[i]-k+n)%n;
                
                for(i=0;i<m;i++) c[i]=0;
                for(i=0;i<n;i++) c[x[y[i]]]++;
                for(i=1;i<m;i++) c[i]+=c[i-1];
                for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
                
                swap(x,y);
                p=1; x[sa[0]]=0;
                for(i=1;i<n;i++){
                    x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
                }
                if(p>=n) break;
                m=p;
            }
        }
        int rank[maxn],height[maxn];
        void getHeight(){
            int i,j,k=0;
            for(i=0;i<n;i++) rank[sa[i]]=i;
            for(i=0;i<n;i++){
                if(k) k--;
                if(rank[i]-1<0) continue; 
                int j=sa[rank[i]-1];
                while(s[i+k]==s[j+k]) k++;
                height[rank[i]]=k;
            }
        }
        void solve(){
        	build_sa();
    //    	for(int i=0;i<n;i++) printf("%s
    ",s+sa[i]);
        	getHeight();
    //    	for(int i=1;i<n;i++) printf("%d ",height[i]);
    //		puts(""); 
        	int ans=0;
        	for(int i=1;i<n;i++){
        		if(height[i]>height[i-1]) ans+=height[i]-height[i-1];
    		}
    		printf("%d
    ",ans);
    	}
    }mysa;
    
    char str[maxn];
    
    int main() {
        int tc,kase=0;
        scanf("%d",&tc);
        while(tc--){
        	scanf("%s",&str);
        	int n=strlen(str);
            mysa.init(n+1,256);
            strcpy(mysa.s,str);
            mysa.solve();
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    第一章 工欲善其事 必先利其器—Android SDK工具(3)
    UVa 11063
    Remember the Word,LA3942(Trie树+DP)
    Atitit.Gui控件and面板----数据库区-mssql 2008 权限 配置 报表查看成员
    Android手机令牌教程
    cocos2d-x 在mac下执行 demo
    Install Oracle 10g on Red Hat Linux 5.3 Step by Step
    Python根据内嵌的数字将字符串排序(sort by numbers embedded in strings)
    mysql一次运行多个SQL文件
    CentOS/Linux 卸载MATLAB
  • 原文地址:https://www.cnblogs.com/fenice/p/5768926.html
Copyright © 2011-2022 走看看