CF1575L Longest Array Deconstruction / 原题链接
其实这道题不用高级数据结构 2333
题意
如果将 \(a_i\) 移动到 \(i\),那么需要 \(a_i\le i\)。
考虑两个相邻的位置 \(p,q\),如果想让它们都有让答案加一的可能,要有:
\[a_p<a_q\\p-a_p\le q-a_q \]而且发现这两个不等式同时也保证了 \(p<q\)。
对于不相邻的 \(p,q\),会依次考虑 \(p,p+1,p+2...q-1,q\),从而保证不会出错。
于是就相当于求 \((i-a_i,a_i)\) 的 LIS。用 lower_bound 计算即可。
时间复杂度 \(O(nlogn)\)。
代码
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;
const int n7=201234;
struct dino{int x,y;}a[n7];
int n,b[n7],cnt,poi;
int rd(){
int shu=0;bool fu=0;char ch=getchar();
while( !isdigit(ch) )fu|=(ch=='-'),ch=getchar();
while( isdigit(ch) )shu=shu*10+ch-'0',ch=getchar();
return fu?-shu:shu;
}
bool cmp(dino p,dino q){return p.x==q.x?p.y<q.y:p.x<q.x;}
int main(){
n=rd();
rep(i,1,n){
int w=rd();
if(i-w>=0)cnt++,a[cnt]=(dino){i-w,w};
}
if(!cnt){puts("0");return 0;}
sort(a+1,a+cnt+1,cmp);
poi=1,b[1]=a[1].y;
rep(i,2,cnt){
if(a[i].y>b[poi])poi++,b[poi]=a[i].y;
else b[lower_bound(b+1,b+poi+1,a[i].y)-b]=a[i].y;
}
printf("%d",poi);
return 0;
}