zoukankan      html  css  js  c++  java
  • BZOJ2534 Uva10829L-gap字符串 字符串 SA ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9240665.html

    题目传送门 - BZOJ2534

    题意

      有一种形如 $uvu$ 形式的字符串,其中 $u$ 是非空字符串,且 $V$ 的长度正好为 $L$ ,那么称这个字符串为 $L-Gap$ 字符串。

      给出一个字符串 $S$ ,以及一个正整数 $L$ ,问 $S$ 中有多少个 $L-Gap$ 子串。

      $L< |S|leq 5 imes 10^4$

    题解

      我甚至怀疑写这题题解是否必要……

      这题和BZOJ2119简直一毛一样啊。

    BZOJ2119 股市的预测 字符串 SA ST表

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    int n,m,tot=0,a[N];
    char s[N];
    map <int,int> mp;
    int SA[N],rank[N],tmp[N],height[N],tax[N];
    int ST[N][20];
    void Sort(int n,int m){
        for (int i=0;i<=m;i++)
    		tax[i]=0;
    	for (int i=1;i<=n;i++)
    		tax[rank[i]]++;
    	for (int i=1;i<=m;i++)
    		tax[i]+=tax[i-1];
    	for (int i=n;i>=1;i--)
    		SA[tax[rank[tmp[i]]]--]=tmp[i];
    }
    bool cmp(int rk[],int x,int y,int w){
    	return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
    }
    void Suffix_Array(int s[],int n){
    	memset(SA,0,sizeof SA);
    	memset(tmp,0,sizeof tmp);
    	memset(rank,0,sizeof rank);
    	memset(height,0,sizeof height);
    	for (int i=1;i<=n;i++)
    		rank[i]=s[i],tmp[i]=i;
    	int m=234;
    	Sort(n,m);
    	for (int w=1,p=0;p<n;w<<=1,m=p){
    		p=0;
    		for (int i=n-w+1;i<=n;i++)
    			tmp[++p]=i;
    		for (int i=1;i<=n;i++)
    			if (SA[i]>w)
    				tmp[++p]=SA[i]-w;
    		Sort(n,m);
    		swap(rank,tmp);
    		rank[SA[1]]=p=1;
    		for (int i=2;i<=n;i++)
    			rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
    	}
    	for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
    		for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
    	height[1]=0;
    }
    void Get_ST(int n){
    	memset(ST,0,sizeof ST);
    	for (int i=1;i<=n;i++){
    		ST[i][0]=height[i];
    		for (int j=1;j<20;j++){
    			ST[i][j]=ST[i][j-1];
    			if (i-(1<<(j-1))>0)
    				ST[i][j]=min(ST[i][j],ST[i-(1<<(j-1))][j-1]);
    		}
    	}
    }
    int Query(int L,int R){
    	int val=floor(log(R-L+1)/log(2));
    	return min(ST[L+(1<<val)-1][val],ST[R][val]);
    }
    int LCP(int x,int y){
    	x=rank[x],y=rank[y];
    	return Query(min(x,y)+1,max(x,y));
    }
    int LCS(int x,int y){
    	return LCP(n*2+2-x,n*2+2-y);
    }
    int main(){
    	scanf("%d",&m);
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	for (int i=1;i<=n;i++)
    		a[i]=a[n*2+2-i]=s[i];
    	a[n+1]=233;
    	Suffix_Array(a,n*2+1);
    	Get_ST(n*2+1);
    	LL ans=0;
    	for (int L=1;L<=n;L++)
    		for (int i=1;i+L+m<=n;i+=L){
    			int x=i,y=i+L+m;
    			int lcp=min(LCP(x,y),L),lcs=min(LCS(x,y),L);
    			int len=lcp+lcs-(lcp>0&&lcs>0);
    			ans+=max(len-L+1,0);
    		}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    代码写界面的工厂类
    Masonry的一些等间距布局
    开发中的小细节随记
    ios7 实现应用内保真截屏
    利用GCD实现单利模式的宏代码
    AVAudioPlayer的锁屏播放控制和锁屏播放信息显示
    NSXMLParser自定义的一个xml解析工具
    利用NSURLSession完成的断点续传功能
    AVFoundation下的视频分帧处理
    Redis自学笔记:4.2进阶-过期时间
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/9240665.html
Copyright © 2011-2022 走看看