单词背诵
P1381 单词背诵
我们发现,前后两个问题完全独立,我们先找出整个序列中共出现了多少个单词,扫一遍即可。
后面的问题就类似于逛画展了,我们只需要用尺取法解决。
英文字母当作下标太麻烦,所以用STL哈希一下。
时间复杂度线性。(刚开始还想着二分,后来发现直接求解就好了)。
#include<iostream>
#include<unordered_map>
#include<cstring>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while
const int N=100010,M=1010;
unordered_map<string,int>mp;
int cnt[M],n,m,a[N];
int calc(int mid){
memset(cnt+1,0,n*4);
int ans=N;
int r=0,tot=0;
E(l, m){
Wh(r<m&&tot<mid)
a[++r]&&!cnt[a[r]]++&&++tot;
if(r==m&&tot<mid)break;
ans=min(ans,r-l+1);
!--cnt[a[l]]&&--tot;
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
E(i, n){
string s;
cin>>s;
mp[s]=i;
}
cin>>m;
E(i, m){
string s;
cin>>s;
a[i]=mp.find(s)!=mp.end()?mp[s]:0;
}
int tot=0;
E(i, m)
a[i]&&!cnt[a[i]]++&&++tot;
cout<<tot<<'\n'<<(tot?calc(tot):0);
return 0;
}