先将n个单词插入哈希表,记录左右端点,每次右端点往后移动,读入一个新的单词并记录下它的哈希值,如果这个单词之前没出现过那么更新(ans)和(minl),如果左端点的单词出现了不止一次则可以往右缩,从而保证长度最短。
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
int ans=0,fh=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
fh=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
return ans*fh;
}
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e5+100,maxm=1e3+100;
const ull base=131,P=1e6+3;
struct hash{
int siz[P],cz[P];
inline ull gethash(char *s){
ull ans=0;
for(int i=0,L=strlen(s);i<L;i++)
ans=(ans*base+s[i])%P;
return ans;
}
// inline void revise(char *s,int z){
// ull x=gethash(s);
// siz[x]+=z;
// }
inline void insert(char *s){
ull x=gethash(s);
cz[x]=1;
}
// inline int query(char *s){
// ull x=gethash(x);
// return siz[x];
// }
inline int find(char *s){
ull x=gethash(s);
if(!cz[x]) x=-1;
return x;
}
}h;
int n,a[maxn],m,ans,minl;
char s[maxm];
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",s),h.insert(s);
scanf("%d",&m);
int l=0;
for(int i=1;i<=m;i++){
scanf("%s",s);
int x=h.find(s);
a[i]=x;
if(~x){
if(h.siz[x]==0) ans++,minl=i-l;
h.siz[x]++;
while(a[l+1]==-1||h.siz[a[l+1]]>1)
l++,h.siz[a[l]]--,minl=min(minl,i-l);
}
}
printf("%d
%d
",ans,minl);
return 0;
}