zoukankan      html  css  js  c++  java
  • [TJOI2017]DNA——后缀数组求LCP

    题目大意:

    给定一个文本串和一个模式串,求文本串中有多少个连续的子串和模式串相差不超过三个字符。

    思路:

    算是一道后缀数组的模板题。

    直接做lcp,然后遇到匹配不上的就跳,跳的次数不能超过三次。

    具体地,将两个字符串连在一起,中间加一个分隔符,然后求出height,用rmq维护height数组的区间最小值即可。

    /*=======================================
     * Author : ylsoi
     * Time : 2019.2.5
     * Problem : luogu3763
     * E-mail : ylsoi@foxmail.com
     * ====================================*/
    #include<bits/stdc++.h>
    
    #define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
    #define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
    #define debug(x) cout<<#x<<"="<<x<<" "
    #define fi first
    #define se second
    #define mk make_pair
    #define pb push_back
    typedef long long ll;
    
    using namespace std;
    
    void File(){
        freopen("luogu3763.in","r",stdin);
        freopen("luogu3763.out","w",stdout);
    }
    
    template<typename T>void read(T &_){
    	_=0; T fl=1; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1;
    	for(;isdigit(ch);ch=getchar())_=(_<<1)+(_<<3)+(ch^'0');
    	_*=fl;
    }
    
    const int maxn=2e5+10;
    int T;
    int n,m;
    char s[maxn];
    int sz,sa[maxn],tp[maxn],rk[maxn],tax[maxn],height[maxn];
    int st[maxn][21],Log[maxn];
    
    void radix_sort(){
    	REP(i,1,sz)tax[i]=0;
    	REP(i,1,n)++tax[rk[i]];
    	REP(i,1,sz)tax[i]+=tax[i-1];
    	DREP(i,n,1)sa[tax[rk[tp[i]]]--]=tp[i];
    }
    
    void suffix_sort(){
    	sz=26;
    	REP(i,1,n)rk[i]=s[i]-'A'+1,tp[i]=i;
    	radix_sort();
    	for(int w=1,p=0;w<n;w<<=1){
    		p=0;
    		REP(i,1,w)tp[++p]=n-w+i;
    		REP(i,1,n)if(sa[i]>w)tp[++p]=sa[i]-w;
    		radix_sort();
    		swap(rk,tp);
    		rk[sa[1]]=p=1;
    		REP(i,2,n)
    			if(tp[sa[i-1]]==tp[sa[i]] && tp[sa[i-1]+w]==tp[sa[i]+w])rk[sa[i]]=p;
    			else rk[sa[i]]=++p;
    		sz=p;
    		if(sz==n)break;
    	}
    }
    
    void get_height(){
    	int k=0;
    	REP(i,1,n){
    		if(k)--k;
    		int j=sa[rk[i]-1];
    		while(s[i+k]==s[j+k])++k;
    		height[rk[i]]=k;
    	}
    }
    
    void init_st(){
    	REP(i,1,n)st[i][0]=height[i];
    	REP(j,1,Log[n])REP(i,1,n-(1<<j)+1)
    		st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    }
    
    int lcp(int x,int y){
    	x=rk[x],y=rk[y];
    	if(x>y)swap(x,y);
    	++x;
    	int d=Log[y-x+1];
    	return min(st[x][d],st[y-(1<<d)+1][d]);
    }
    
    int main(){
    	File();
    	REP(i,2,2e5)Log[i]=Log[i>>1]+1;
    	read(T);
    	while(T--){
    		scanf("%s",s+1);
    		m=strlen(s+1)+1;
    		s[m]='Z';
    		scanf("%s",s+m+1);
    		n=strlen(s+1);
    		suffix_sort();
    		get_height();
    		init_st();
    		int ans=0;
    		REP(i,1,m-n+m){
    			int p=0,len;
    			REP(j,1,4){
    				len=lcp(i+p,m+1+p);
    				p+=len;
    				if(p==n-m){++ans; break;}
    				else ++p;
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    互联网博物馆
    CSS简介和CSS选择器
    perl 面向对象 use base
    mysql tcp 4层负载
    mysql tcp 4层负载
    mysql Emoji表情字符集转换
    mysql Emoji表情字符集转换
    html submit 登录
    html submit 登录
    haroxy hdr
  • 原文地址:https://www.cnblogs.com/ylsoi/p/10353533.html
Copyright © 2011-2022 走看看