Codeforces 92C【二分】
意:
求最少需要几个s1串拼接存在子串s2 (1≤|s1|≤1e4,1≤|s2|≤1e6).
思路(感谢ZQC):
每个字母的出现位置存个vector.
假设你当前已经用了A串的前x个字符,现在想要匹配一个'x',那你就在'x'的vector那里二分出第一个大于x的位置,
如果匹配不到的话,就相当于需要一个新的串。
#include <bits/stdc++.h> using namespace std; typedef long long LL; vector<int>xs[30]; char s1[10010],s2[1000010]; map<int,int>mp; int main() { int x,n,m,pos,ans,k; vector<int>::iterator y; scanf("%s%s",s1,s2); n=strlen(s1); for(int i=0;i<n;i++) { x=s1[i]-'a'; xs[x].push_back(i); mp[x]=1; } m=strlen(s2); pos=-1; ans=1; for(int i=0;i<m;i++) { x=s2[i]-'a'; if(!mp[x]) { puts("-1"); return 0; } y=upper_bound(xs[x].begin(),xs[x].end(),pos); if(y==xs[x].end()) { ans++; y=xs[x].begin(); } k=y-xs[x].begin(); pos=xs[x][k]; } printf("%d\n",ans); return 0; }