• uva10829 L-Gap Substrings


    传送门:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&page=show_problem&problem=1770

    思路:这题和上一题SPOJ687的思路一样,也是枚举长度,再对于i和i+j+L向前向后匹配,但是这一题只能在后面接一个反串。


    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int maxn=100010;
    using namespace std;
    int n,sum[maxn],t1[maxn],t2[maxn],sa[maxn],rank[maxn],h[maxn],st[maxn][20],L,len;char s[maxn];long long ans;
    
    void getsa(){
    	int *x=t1,*y=t2,m=255,p=0;
    	for (int i=1;i<=n;i++) sum[x[i]=s[i]]++;
    	for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
    	for (int i=n;i;i--) sa[sum[x[i]]--]=i;
    	for (int j=1;p<n;j<<=1,m=p){
    		p=0;
    		for (int i=n-j+1;i<=n;i++) y[++p]=i;
    		for (int i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;
    		memset(sum,0,sizeof(sum));
    		for (int i=1;i<=n;i++) sum[x[y[i]]]++;
    		for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
    		for (int i=n;i;i--) sa[sum[x[y[i]]]--]=y[i];
    		swap(x,y),x[sa[1]]=p=1;
    		for (int i=2;i<=n;i++){
    			if (y[sa[i]]!=y[sa[i-1]]||y[sa[i]+j]!=y[sa[i-1]+j]) p++;
    			x[sa[i]]=p;
    		}
    	}
    	memcpy(rank,x,sizeof(rank));
    }
    
    void geth(){
    	for (int i=1,j=0;i<=n;i++){
    		if (rank[i]==1) continue;
    		while (s[i+j]==s[sa[rank[i]-1]+j]) j++;
    		h[rank[i]]=j;
    		if (j) j--;
    	}
    }
    
    void getst(){
    	for (int i=1;i<=n;i++) st[i][0]=h[i];
    	for (int j=1;j<=19;j++)
    		for (int i=1;i+(1<<j)-1<=n;i++)
    			st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    }
    
    int getmin(int x,int y){
    	int l=rank[x],r=rank[y];
    	if (l>r) swap(l,r);
    	l++;int k=log2(r-l+1);
    	return min(st[l][k],st[r-(1<<k)+1][k]);
    }
    
    int main(){
    	scanf("%d%s",&L,s+1);
    	len=strlen(s+1),s[n=len+1]=127;
    	for (int i=len;i;i--) s[++n]=s[i];s[n+1]=0;
    	getsa(),geth(),getst();
    	for (int i=1;i+i+L<=len;i++)
    		for (int j=1;j<=len;j+=i){
    			int k=j+i+L,tmp=0;
    			if (k<=len) tmp+=min(i,getmin(j,k));
    			if (j>=2) tmp+=min(i-1,getmin(n-j+2,n-k+2));
    			ans+=max(0,tmp-i+1);
    		}
    	printf("%lld
    ",ans);
    	return 0;
    }


  • 相关阅读:
    SQL TOP 分页
    C# Word 打印
    Oracle 11g 卸载日志
    用 16G 内存存放 30亿数据(Java Map)转载
    HTMLDivElement.prototype
    在TOMCAT8.5使用 JOSSO 单点登录(Agent 端)
    德哥的PostgreSQL私房菜
    Object-relational impedance mismatch (转载)
    Java性能最后一个领域:去除垃圾回收器
    我们为什么选择Vue.js而不是React(转载)
  • 原文地址:https://www.cnblogs.com/thythy/p/5493531.html
Copyright © 2020-2023  润新知