CF149E Martian Strings [后缀自动机]

板子
注意特判一下能直接拼凑出来的。

// clang-format off
// powered by c++11
// by Isaunoya
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define Rep(i,x,y) for(register int i=(x);i>=(y);--i)
using namespace std;using db=double;using ll=long long;
using uint=unsigned int;using ull=unsigned long long;
using pii=pair<int,int>;
#define Tp template
#define fir first
#define sec second
Tp<class T>void cmax(T&x,const T&y){if(x<y)x=y;}Tp<class T>void cmin(T&x,const T&y){if(x>y)x=y;}
#define all(v) v.begin(),v.end()
#define sz(v) ((int)v.size())
#define pb emplace_back
Tp<class T>void sort(vector<T>&v){sort(all(v));}Tp<class T>void reverse(vector<T>&v){reverse(all(v));}
Tp<class T>void unique(vector<T>&v){sort(all(v)),v.erase(unique(all(v)),v.end());}inline void reverse(string&s){reverse(s.begin(),s.end());}
const int SZ=1<<23|233;
struct FILEIN{char qwq[SZ],*S=qwq,*T=qwq,ch;
#ifdef __WIN64
#define GETC getchar
#else
inline char GETC(){return(S==T)&&(T=(S=qwq)+fread(qwq,1,SZ,stdin),S==T)?EOF:*S++;}
#endif
inline FILEIN&operator>>(char&c){while(isspace(c=GETC()));return*this;}inline FILEIN&operator>>(string&s){s.clear();while(isspace(ch=GETC()));if(!~ch)return*this;s=ch;while(!isspace(ch=GETC())&&~ch)s+=ch;return*this;}
inline FILEIN&operator>>(char*str){char*cur=str;while(*cur)*cur++=0;cur=str;while(isspace(ch=GETC()));if(!~ch)return*this;*cur=ch;while(!isspace(ch=GETC())&&~ch)*++cur=ch;*++cur=0;return*this;}
Tp<class T>inline void read(T&x){bool f=0;while((ch=GETC())<48&&~ch)f^=(ch==45);x=~ch?(ch^48):0;while((ch=GETC())>47)x=x*10+(ch^48);x=f?-x:x;}
inline FILEIN&operator>>(int&x){return read(x),*this;}inline FILEIN&operator>>(ll&x){return read(x),*this;}inline FILEIN&operator>>(uint&x){return read(x),*this;}inline FILEIN&operator>>(ull&x){return read(x),*this;}
inline FILEIN&operator>>(double&x){read(x);bool f=x<0;x=f?-x:x;if(ch^'.')return*this;double d=0.1;while((ch=GETC())>47)x+=d*(ch^48),d*=.1;return x=f?-x:x,*this;}
}in;
struct FILEOUT{const static int LIMIT=1<<22;char quq[SZ],ST[233];int sz,O,pw[233];
FILEOUT(){set(7);rep(i,pw[0]=1,9)pw[i]=pw[i-1]*10;}~FILEOUT(){flush();}
inline void flush(){fwrite(quq,1,O,stdout),fflush(stdout),O=0;}
inline FILEOUT&operator<<(char c){return quq[O++]=c,*this;}inline FILEOUT&operator<<(string str){if(O>LIMIT)flush();for(char c:str)quq[O++]=c;return*this;}
inline FILEOUT&operator<<(char*str){if(O>LIMIT)flush();char*cur=str;while(*cur)quq[O++]=(*cur++);return*this;}
Tp<class T>void write(T x){if(O>LIMIT)flush();if(x<0){quq[O++]=45;x=-x;}do{ST[++sz]=x%10^48;x/=10;}while(x);while(sz)quq[O++]=ST[sz--];}
inline FILEOUT&operator<<(int x){return write(x),*this;}inline FILEOUT&operator<<(ll x){return write(x),*this;}inline FILEOUT&operator<<(uint x){return write(x),*this;}inline FILEOUT&operator<<(ull x){return write(x),*this;}
int len,lft,rig;void set(int l){len=l;}inline FILEOUT&operator<<(double x){bool f=x<0;x=f?-x:x,lft=x,rig=1.*(x-lft)*pw[len];return write(f?-lft:lft),quq[O++]='.',write(rig),*this;}
}out;
#define int long long
struct Math{
vector<int>fac,inv;int mod;
void set(int n,int Mod){fac.resize(n+1),inv.resize(n+1),mod=Mod;rep(i,fac[0]=1,n)fac[i]=fac[i-1]*i%mod;inv[n]=qpow(fac[n],mod-2);Rep(i,n-1,0)inv[i]=inv[i+1]*(i+1)%mod;}
int qpow(int x,int y){int ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1)ans=ans*x%mod;return ans;}int C(int n,int m){if(n<0||m<0||n<m)return 0;return fac[n]*inv[m]%mod*inv[n-m]%mod;}
int gcd(int x,int y){return!y?x:gcd(y,x%y);}int lcm(int x,int y){return x*y/gcd(x,y);}
}math;
// clang-format on
const int maxn = 2e5 + 52;
struct suffix_auto_maton {
  int ch[maxn][26], fa[maxn], len[maxn];
  int las, cnt;
  suffix_auto_maton() { las = cnt = 1; }

  int pos[maxn];

  void ins(int c, int id) {
    int p = las, np = las = ++cnt;
    pos[np] = id;
    for (len[np] = len[p] + 1; p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
    if (!p) {
      fa[np] = 1;
    } else {
      int q = ch[p][c];
      if (len[q] == len[p] + 1) {
        fa[np] = q;
      } else {
        int nq = ++cnt;
        memcpy(ch[nq], ch[q], sizeof(ch[q])), pos[nq] = pos[q];
        for (fa[nq] = fa[q], len[nq] = len[p] + 1, fa[np] = fa[q] = nq; p && ch[p][c] == q; p = fa[p])
          ch[p][c] = nq;
      }
    }
  }

  void ins(char *s, int qwq) {
    char *cur = s;
    if (!qwq) {
      int cnt = 0;
      while (*cur) ins((*cur++) - 'A', ++cnt);
    } else {
      int cnt = qwq;
      while (*cur) ins((*cur++) - 'A', cnt--);
    }
  }

  vector<int> g[maxn];
  int mn[maxn], mx[maxn];
  void dfs(int u) {
    mn[u] = mx[u] = pos[u];
    for (int v : g[u]) {
      dfs(v);
      cmin(mn[u], mn[v]);
      cmax(mx[u], mx[v]);
    }
  }

  void build() {
    rep(i, 2, cnt) g[fa[i]].pb(i);
    dfs(1);
  }

} pre, suf;

char s[maxn], t[maxn];
int A[maxn], B[maxn];

signed main() {
  // code begin.
  in >> s;
  pre.ins(s, 0);
  int len = strlen(s);
  t[len] = 0;
  for (char *cur = s; *cur; ++cur) t[--len] = *cur;
  len = strlen(s);
  suf.ins(t, len);
  pre.build(), suf.build();
  int _;
  in >> _;
  int ans = 0;
  while (_--) {
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    in >> s;
    int len = strlen(s);
    t[len] = 0;
    for (char *cur = s; *cur; ++cur) t[--len] = *cur;
    char *cur = s;
    int p = 1;
    while (*cur) {
      int c = (*cur++) - 'A';
      if (pre.ch[p][c]) {
        p = pre.ch[p][c];
        A[++len] = pre.mn[p];
      } else
        break;
    }

    cur = t;
    p = 1;
    len = strlen(s);
    while (*cur) {
      int c = (*cur++) - 'A';
      if (suf.ch[p][c]) {
        p = suf.ch[p][c];
        B[len--] = suf.mx[p];
      } else
        break;
    }

    int flag = 0;
    len = strlen(s);
    rep(i, 1, len - 1) if (A[i] && B[i + 1] && A[i] < B[i + 1]) flag = 1;
    if (A[len]) flag = 1;
    if (len == 1) flag = 0;
    ans += flag;
  }
  out << ans << '\n';
  return 0;
  // code end.
}
posted @ 2020-03-25 19:26  _Isaunoya  阅读(131)  评论(0编辑  收藏  举报