BZOJ 1212 L语言(DP+字典树)

时间:2023-03-09 18:43:50
BZOJ 1212 L语言(DP+字典树)

求能被理解的最长前缀。

很显然的dp。令dp[i]=true,表示前缀i能理解。否则不能理解。那么dp[i+len]=dp[i]=true,当s[len]能匹配str[i,i+len].

由于模式串长度为10.且匹配过程可以用字典树加速。

所以复杂度就是O(10*m*len).

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int trie[][], top;
char str[N], s[];
bool vis[N]; void init(){top=; mem(trie[],);}
void ins(char *s){
int rt, nxt;
for (rt=; *s; rt=nxt, ++s){
nxt=trie[rt][*s-'a'];
if (!nxt) mem(trie[top],), trie[rt][*s-'a']=nxt=top++;
}
trie[rt][]=;
}
void find(int l, int r){
int rt, nxt, i;
for (rt=, i=l; i<=r; rt=nxt, ++i) {
nxt=trie[rt][str[i]-'a'];
if (!nxt) return ;
if (trie[nxt][]) vis[i]=true;
}
}
int main ()
{
int n, m;
scanf("%d%d",&n,&m); init();
FOR(i,,n) scanf("%s",s+), ins(s+);
FOR(i,,m) {
scanf("%s",str+);
int len=strlen(str+);
mem(vis,); vis[]=true;
int ans;
FOR(j,,len) if (vis[j]) find(j+>len?len:j+,j+>len?len:j+), ans=j;
printf("%d\n",ans);
}
return ;
}