bzoj4892 [Tjoi2017]dna(SAM/SA/二分答案+Hash)
2018-03-26 15:57
381 查看
在后缀自动机上跑一跑就好啦。O(n)O(n)
SA题解:portalO(nlogn)O(nlogn)
upd:还可以二分答案+Hash来求lcp哟。O(nlogn)O(nlogn)
SA题解:portalO(nlogn)O(nlogn)
upd:还可以二分答案+Hash来求lcp哟。O(nlogn)O(nlogn)
SAM
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 200010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } char s ; int id['Z'],n=0,m,rt,last,mx ,son [4],par ,ans,hh ,a ,ri ; inline void ins(int ch){ int p=last,np=++n;last=np;mx[np]=mx[p]+1;ri[np]=1; for(;p&&!son[p][ch];p=par[p]) son[p][ch]=np; if(!p){par[np]=rt;return;} int q=son[p][ch];if(mx[q]==mx[p]+1){par[np]=q;return;} int nq=++n;memcpy(son[nq],son[q],sizeof(son[q])); mx[nq]=mx[p]+1;par[nq]=par[q];par[q]=par[np]=nq; for(;p&&son[p][ch]==q;p=par[p]) son[p][ch]=nq; } void dfs(int p,int j,int cnt){ if(j>m){ans+=ri[p];return;} for(int i=0;i<4;++i){ if(!son[p][i]) continue; if(id[s[j]]==i) dfs(son[p][i],j+1,cnt); else if(cnt+1<=3) dfs(son[p][i],j+1,cnt+1); } } int main(){ // freopen("a.in","r",stdin); int tst=read();id['A']=0;id['T']=1;id['C']=2;id['G']=3; while(tst--){ n=0;last=rt=++n;ans=0;memset(ri,0,sizeof(ri));memset(son,0,sizeof(son)); scanf("%s",s+1);int len=strlen(s+1); for(int i=1;i<=len;++i) ins(id[s[i]]); memset(hh,0,sizeof(hh)); for(int i=1;i<=n;++i) hh[mx[i]]++; for(int i=1;i<=len;++i) hh[i]+=hh[i-1]; for(int i=n;i>=1;--i) a[hh[mx[i]]--]=i; for(int i=n;i>=1;--i){int p=a[i];ri[par[p]]+=ri[p];} scanf("%s",s+1);m=strlen(s+1);dfs(rt,1,0);printf("%d\n",ans); }return 0; }
二分答案+Hash
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ull unsigned long long #define inf 0x3f3f3f3f #define N 100010 #define k1 11117 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } char s1 ,s2 ; ull hs1 ,hs2 ,bin ; int n,m; inline ull cal1(int l,int r){ return hs1[r]-hs1[l-1]*bin[r-l+1]; } inline ull cal2(int l,int r){ return hs2[r]-hs2[l-1]*bin[r-l+1]; } inline int lcp(int l1,int l2){ int l=1,r=m-l2+1; while(l<=r){ int mid=l+r>>1; if(cal1(l1,l1+mid-1)==cal2(l2,l2+mid-1)) l=mid+1; else r=mid-1; }return l-1; } int main(){ // freopen("a.in","r",stdin); int tst=read();bin[0]=1; while(tst--){ scanf("%s",s1+1);n=strlen(s1+1); scanf("%s",s2+1);m=strlen(s2+1);int ans=0; for(int i=1;i<=n;++i) bin[i]=bin[i-1]*k1; for(int i=1;i<=n;++i) hs1[i]=hs1[i-1]*k1+s1[i]; for(int i=1;i<=m;++i) hs2[i]=hs2[i-1]*k1+s2[i]; for(int i=1;i<=n;++i){ if(i+m-1>n) break; int p1=1,p2=1; for(int hhh=1;hhh<=4;++hhh){ int x=lcp(i+p1-1,p2);p1+=x;p2+=x; if(hhh!=4) p1++,p2++; if(p2>m){ans++;break;} } }printf("%d\n",ans); }return 0; }
相关文章推荐
- bzoj4892: [Tjoi2017]dna
- [BZOJ4892][TJOI2017]DNA(后缀数组)
- bzoj 4892: [Tjoi2017]dna 哈希+二分
- BZOJ_4892_[Tjoi2017]dna_哈希
- bzoj3796 Mushroom追妹纸(SA+二分答案+kmp)
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)
- 【bzoj4552】【Tjoi2016】【Heoi2016】【排序】【二分答案】【线段树】
- bzoj4556 [Tjoi2016&Heoi2016]字符串(SA+二分答案+线段树)
- bzoj4829 [TJOI2017]dna(后缀数组)
- BZOJ3998 TJOI2015弦论(后缀数组+二分答案)
- 【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】
- BZOJ 1567: [JSOI2008]Blue Mary的战役地图( 二分答案 + hash )
- BZOJ4952 [Wf 2017] 二分答案 解题报告
- BZOJ2258 文本校对 (Splay Hash 二分答案)
- BZOJ 1014 火星人 prefix (splay hash 二分答案)
- [BZOJ4890][TJOI2017]城市(DP)
- 【BZOJ1189】紧急疏散(二分答案,最大流)
- BZOJ 1082: [SCOI2005]栅栏 DFS,剪枝,二分答案
- BZOJ 3761 甄嬛 二分答案
- BZOJ 1044 HAOI2008 木棍切割 二分答案+动态规划