Removed Interval HDU

来源:互联网 发布:证券软件下载 编辑:程序博客网 时间:2024/06/05 03:36

问一个n元序列任删掉一段m长的子段后的LIS长度

n1e5,考虑枚举剩下的右端点参与答案贡献,我们需要右端点开始的LIS,以及删除段左边的,刚好比右端点小的点往前跑的LIS

前者可以去个负倒过来跑一下,后者双针边跑边更新就行

//#include<bits/stdc++.h>  //#pragma comment(linker, "/STACK:1024000000,1024000000")   #include<stdio.h>  #include<algorithm>  #include<queue>  #include<string.h>  #include<iostream>  #include<math.h>  #include<set>  #include<map>  #include<vector>  #include<iomanip>  using namespace std;    const double pi=acos(-1.0);  #define ll long long  #define pb push_back#define sqr(a) ((a)*(a))#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))#define FOR(a) for(int i=1;i<=a;i++)const double eps=1e-10;const int maxn=1e5+56;const int inf=0x3f3f3f3f;int a[maxn],b[maxn],dp[maxn],f[maxn];int main(){int T;scanf("%d",&T);int kase=0;while(T--){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=-a[i];}memset(dp,0x3f,sizeof dp);for(int i=n;i>=1;i--){int t=lower_bound(dp+1,dp+1+n,b[i])-dp;f[i]=t;//i开头的最长长度dp[t]=b[i];}memset(dp,0x3f,sizeof dp);int ans=0;for(int i=m+1;i<=n;i++){//枚举右端点int t=lower_bound(dp+1,dp+1+n,a[i])-dp;ans=max(ans,t-1+f[i]);*lower_bound(dp+1,dp+1+n,a[i-m])=a[i-m];}//在求左边lis过程中找右端点的lbint t=lower_bound(dp+1,dp+1+n,inf)-dp;//全左ans=max(ans,t-1);printf("Case #%d: %d\n",++kase,ans);}}