题目链接:http://codeforces.com/contest/779/problem/D
题意:给你一段操作序列,按顺序依次删掉字符串1中相应位置的字符,问你最多能按顺序删掉多少个字符,使得s2是剩下的字符构成的字符串的子列。
字符串长度为2e5每次查询的时间复杂度为n如果直接暴力那么复杂度就是n*n
如果二分一下答案的话复杂度就是n*logn再加上修改的复杂度总的复杂度是
(n+n)* logn
#include <iostream> #include <cstring> #include <string> using namespace std; const int M = 2e5 + 10; string p , t; int a[M] , l , r , mid; bool vis[M]; bool find(int pos) { int len = t.size() , len2 = p.size(); int count = 0; for(int i = 0 ; i < len ; i++) { if(i <= mid) { vis[a[i] - 1] = false; } else { vis[a[i] - 1] = true; } } for(int i = 0 ; i < len ; i++) { if(vis[i]) { if(t[i] == p[count]) { count++; } } if(count == len2) return true; } return false; } int main() { cin >> t >> p; int len = t.size(); for(int i = 0 ; i < len ; i++) { cin >> a[i]; vis[i] = true; } l = 0 , r = len - 1; while(l <= r) { mid = (l + r) >> 1; int flag = find(mid); if(flag) { l = mid + 1; } else { r = mid - 1; } } cout << r + 1 << endl; return 0; }