• 【BZOJ1396】识别子串(后缀自动机,线段树)


    题意:

     一行,一个由小写字母组成的字符串S,长度不超过10^5

    思路:论文题

     设p为自动机上的合法结点,r为右端点,len=st[fa[p]]]+1

    位置[r-st[p]+1,r-len+1]与r-i+1取min,其中i为下标

    位置[r-len+1,r]与len取min

    建立两棵线段树,分别维护r+1和len

    因为只有区间修改和单点查询可以不写lazytag

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 typedef pair<ll,int>P;
     11 #define N  100010
     12 #define M  210000
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pi acos(-1)
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     20 #define lowbit(x) x&(-x)
     21 #define Rand (rand()*(1<<16)+rand())
     22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     23 #define ls p<<1
     24 #define rs p<<1|1
     25 
     26 const int MOD=1e9+7,inv2=(MOD+1)/2;
     27       double eps=1e-6;
     28       int INF=1e9;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 char s[N];
     34 int p,np,q,nq,k,cas,n;
     35 int t[N<<2][2];
     36 
     37 int read()
     38 {
     39    int v=0,f=1;
     40    char c=getchar();
     41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     43    return v*f;
     44 }
     45 
     46 void build(int l,int r,int p,int op)
     47 {
     48     t[p][op]=INF;
     49     if(l==r) return;
     50     int mid=(l+r)>>1;
     51     build(l,mid,ls,op);
     52     build(mid+1,r,rs,op);
     53 }
     54 
     55 void update(int l,int r,int x,int y,int v,int p,int op)
     56 {
     57     if(x<=l&&r<=y)
     58     {
     59         t[p][op]=min(t[p][op],v);
     60         return;
     61     }
     62     int mid=(l+r)>>1;
     63     if(x<=mid) update(l,mid,x,y,v,ls,op);
     64     if(y>mid) update(mid+1,r,x,y,v,rs,op);
     65 }
     66 
     67 int query(int l,int r,int x,int p,int op)
     68 {
     69     if(l==r) return t[p][op];
     70     int mid=(l+r)>>1;
     71     if(x<=mid) return min(t[p][op],query(l,mid,x,ls,op));
     72      else return min(t[p][op],query(mid+1,r,x,rs,op));
     73 }
     74 
     75 struct sam
     76 {
     77     int cnt;
     78     int fa[N<<1],ch[N<<1][26];
     79     int st[N<<1],b[N<<1],bl[N<<1],to[N<<1],size[N<<1];
     80 
     81     sam()
     82     {
     83         cnt=np=1;
     84     }
     85 
     86     void add(int x,int i)
     87     {
     88         p=np; st[np=++cnt]=st[p]+1;
     89         to[np]=i;
     90         while(p&&!ch[p][x])
     91         {
     92             ch[p][x]=np;
     93             p=fa[p];
     94         }
     95         if(!p) fa[np]=1;
     96          else if(st[p]+1==st[q=ch[p][x]]) fa[np]=q;
     97           else
     98           {
     99                   st[nq=++cnt]=st[p]+1;
    100                   memcpy(ch[nq],ch[q],sizeof ch[q]);
    101                   //t[nq]=t[q];
    102                   fa[nq]=fa[q];
    103                   fa[q]=fa[np]=nq;
    104                   while(p&&ch[p][x]==q)
    105                   {
    106                       ch[p][x]=nq;
    107                       p=fa[p];
    108                   }
    109           }
    110     }
    111 
    112     void solve()
    113     {
    114         rep(i,1,cnt) b[st[i]]++;
    115         rep(i,1,cnt) b[i]+=b[i-1];
    116         rep(i,1,cnt) bl[b[st[i]]--]=i;
    117         int u=1;
    118         rep(i,1,n)
    119         {
    120             u=ch[u][s[i]-'a'];
    121             size[u]++;
    122         }
    123         build(1,n,1,0);
    124         build(1,n,1,1);
    125         per(i,cnt,1) size[fa[bl[i]]]+=size[bl[i]];
    126 
    127         rep(i,1,cnt)
    128         {
    129             int p=bl[i];
    130             if(size[p]>1) continue;
    131             int len=st[fa[p]]+1,r=to[p];
    132             update(1,n,r-len+1,r,len,1,0);
    133             update(1,n,r-st[p]+1,r-len+1,r+1,1,1);
    134         }
    135 
    136         rep(i,1,n)
    137         {
    138             int t1=query(1,n,i,1,0),t2=-i+query(1,n,i,1,1);
    139             printf("%d
    ",min(t1,t2));
    140         }
    141 
    142     }
    143 }sam;
    144 
    145 
    146 int main()
    147 {
    148     scanf("%s",s+1);
    149     n=strlen(s+1);
    150     rep(i,1,n) sam.add(s[i]-'a',i);
    151     sam.solve();
    152     return 0;
    153 }
  • 相关阅读:
    【转】CUDA5/CentOS6.4
    【转】centos 6.4 samba 安装配置
    【转】Install MATLAB 2013a on CentOS 6.4 x64 with mode silent
    【转】Getting xrdp to work on CentOS 6.4
    【VLFeat】使用matlab版本计算HOG
    Unofficial Windows Binaries for Python Extension Packages
    March 06th, 2018 Week 10th Tuesday
    March 05th, 2018 Week 10th Monday
    March 04th, 2018 Week 10th Sunday
    March 03rd, 2018 Week 9th Saturday
  • 原文地址:https://www.cnblogs.com/myx12345/p/11507540.html
Copyright © 2020-2023  润新知