额……因为没考虑好题目条件的关系,(WA)了好几次……
把必须要做题的(K)天看作一个个端点
因为这(K)天是我们必须要做题的,而我们又要保证做题数量单调递增,所以我们可以在每两个端点之间筛选出大于左端点小于右端点的数,然后整体跑一遍最长上升子序列,这样就可以保证满足题目条件
无解的情况就是存在一个右端点大于等于右端点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define LL long long
using namespace std;
LL read() {
LL k = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
k = k * 10 + c - 48, c = getchar();
return k * f;
}
int p[500010], a[500010], ans[500010], b[500010], tot;
int main() {
int n = read(), k = read();
for(int i = 1; i <= k; ++i) p[i] = read();
for(int i = 1; i <= n; ++i) a[i] = read();
sort(p+1, p+k+1);
for(int i = 1; i <= p[1]; ++i)
if(a[i] < a[p[1]]) ans[++tot] = a[i];
ans[++tot] = a[p[1]];
for(int i = 2; i <= k; ++i) {
if(a[p[i-1]] >= a[p[i]]) {
printf("impossible
"); return 0;
}
for(int j = p[i-1]+1; j <= p[i]; ++j) {
if(a[j] < a[p[i]] && a[j] > a[p[i-1]]) ans[++tot] = a[j];
}
ans[++tot] = a[p[i]];
}
for(int i = p[k]; i <= n; ++i)
if(a[i] > a[p[k]]) ans[++tot] = a[i];
int cnt = 0;
for(int i = 1; i <= tot; ++i) {
if(ans[i] > b[cnt]) b[++cnt] = ans[i];
else {
int pos = lower_bound(b+1, b+cnt+1, ans[i]) - b;
b[pos] = ans[i];
}
}
cout << cnt << endl;
return 0;
}