题意:对一个数列删除连续长度为L的数剩下的数列的最长递增子序列最大。
思路:先预处理一下以i开始到结尾的数列的以a[i]为LIS 为最后一个数的数的长度,不是LIS !
然后对于这样的话每次枚举i,每次查询操作之后把i - m这个元素加入的数组中。
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define clr(x,y) memset(x,y,sizeof x)
typedef long long ll;
const int maxn = 2e5 + 10;
int a[maxn],b[maxn],c[maxn],d[maxn];
int st[maxn];
int len1[maxn],len2[maxn];
int main()
{
int n,m;
int Tcase;scanf("%d",&Tcase);
for(int ii = 1;ii <= Tcase;ii ++)
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i ++)scanf("%d",&a[i]),b[i] = -a[i];
clr(st,INF);
int cnt = 0;st[++ cnt] = b[n];len2[n] = 1;
for(int i = n - 1;i >= 1; i --)
{
int pos = lower_bound(st + 1,st +cnt + 1,b[i]) - st;
if(pos > cnt)cnt ++;
st[pos] = b[i];len2[i] = pos;
}
int ans = 0;
cnt = 0;clr(st,INF);
for(int i = m + 1; i <= n;i ++)
{
int pos = lower_bound(st + 1,st + cnt + 1,a[i]) - st;
ans = max(ans,pos - 1 + len2[i]);
pos = lower_bound(st + 1,st + cnt + 1,a[i - m]) - st;
if(pos > cnt)cnt ++;
st[pos] = a[i - m];
if(i == n)
{
ans = max(ans,cnt);
}
}
printf("Case #%d: %d\n",ii,ans);
}
return 0;
}