hdu1950 Bridging signals
LIS
nlogn的时间复杂度,之前没有写过。
思路是d[i]保存长度为i的单调不下降子序列末尾的最小值。
更新时候,如果a[i]>d[len],(len为目前最长的单调不下降子序列) d[++len]=a[i]
否则 二分查找 d[j-1]<a[i]<d[j] 并更新 d[j]=a[i]
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define LL long long using namespace std; LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10ll+ch-'0';ch=getchar();} return x*f; } const int maxn = 40000 + 10; int n,len; int a[maxn]; int d[maxn]; int l,r,mid; void build() { n=read(); for(int i=1;i<=n;i++) a[i]=read(); memset(d,0,sizeof(d)); d[1]=a[1]; len=1; for(int i=2;i<=n;i++) { if(a[i]>d[len]) d[++len]=a[i]; else { l=1; r=len; while(l<r) { mid=(l+r)/2; if(d[mid]>a[i]) r=mid; else l=mid+1; } d[l]=a[i]; } } //printf("Tets\n"); //for(int i=1;i<=n;i++) printf("%d ",d[i]); printf("%d\n",len); } void solve() { } int main() { int T; scanf("%d",&T); while(T--) { build(); solve(); } return 0; }