zoukankan      html  css  js  c++  java
  • 洛谷P3763 [TJOI2017]DNA(后缀自动机)

    传送门

    好像用SAM写的很少诶……

    其实我一开始也没想到要用SAM的……主要是没有想到找的时候可以dfs……

    首先建一个SAM,然后跑一遍dfs,枚举一下下一位,如果相同直接继续,否则就花费一次次数来改变它,保证改变次数小于等于3就行了

     1 // luogu-judger-enable-o2
     2 //minamoto
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 const int N=1e6+5;
     8 int cnt[N<<1],fa[N<<1],ch[N<<1][4],l[N<<1],last,tot;
     9 char s[N];int c[N],a[N],ans,m,val[N];
    10 void ins(int c){
    11     int p=last,np=++tot;last=np,l[np]=l[p]+1,cnt[np]=1;
    12     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    13     if(!p) fa[np]=1;
    14     else{
    15         int q=ch[p][c];
    16         if(l[q]==l[p]+1) fa[np]=q;
    17         else{
    18             int nq=++tot;l[nq]=l[p]+1;
    19             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    20             fa[nq]=fa[q],fa[q]=fa[np]=nq;
    21             for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    22         }
    23     }
    24 }
    25 inline void calc(){
    26     memset(c,0,sizeof(c));
    27     for(int i=1;i<=tot;++i) ++c[l[i]];
    28     for(int i=1;i<=tot;++i) c[i]+=c[i-1];
    29     for(int i=1;i<=tot;++i) a[c[l[i]]--]=i;
    30     for(int i=tot,p;i;--i)
    31     p=a[i],cnt[fa[p]]+=cnt[p];
    32 }
    33 void dfs(int p,int len,int j){
    34     if(len>m) return (void)(ans+=cnt[p]);
    35     for(int i=0;i<4;++i){
    36         if(!ch[p][i]) continue;
    37 //        val[s[len]]==i?dfs(ch[p][i],len+1,j):j<3?dfs(ch[p][i],len+1,j+1):(void)(1);
    38         if(val[s[len]]==i) dfs(ch[p][i],len+1,j);
    39         else if(j<3) dfs(ch[p][i],len+1,j+1);
    40     }
    41 }
    42 int main(){
    43 //    freopen("testdata.in","r",stdin);
    44     val['T']=0,val['A']=1,val['C']=2,val['G']=3;
    45     int T;scanf("%d",&T);
    46     while(T--){
    47         memset(ch,0,sizeof(ch)),memset(cnt,0,sizeof(cnt));
    48         last=tot=1,ans=0;
    49         scanf("%s",s+1);int len=strlen(s+1);
    50         for(int i=1;i<=len;++i) ins(val[s[i]]);
    51         calc();
    52         scanf("%s",s+1),m=strlen(s+1);
    53         dfs(1,1,0);printf("%d
    ",ans);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    Mozilla Prism v0.9 For Windows/Linux/Mac
    Firefox 3.0十大年夜新特征(1)
    刊行版:Epidemic GNU/Linux 2.1发布
    斥地版:Red Hat Enterprise Linux 4.7 Beta公布公布
    linux下安装drcom1.3.7心得
    Oracle老手艺对Linux意味着什么?
    学Linux要火山式的驾御还是垂垂来
    Firefox 3.0 RC2本周颁发
    net命令详解 **net accounts /maxpwage:unlimited
    学习官方示例 TApplication.OnDeactivate
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9643215.html
Copyright © 2011-2022 走看看