http://acm.hdu.edu.cn/showproblem.php?pid=3564
(1)插入元素;求最长上升子序列。
他人具体代码:
View Code
#include<stdio.h> #include<string.h> #define lowbit(i) (i&(-i)) const int MAXN=100005; const int MAXLOG=17; int B[MAXN],pos[MAXN]; int N; void update(int i,int value){ //维护空位的个数 for(;i<=N;i+=lowbit(i)) B[i]+=value; } int getK(int k){//返回第k个空位的下标 int ans=0; for(int i=MAXLOG;i>=0;i--) { ans+=(1<<i); if(ans>N||B[ans]>=k) ans-=(1<<i); else k-=B[ans]; } return ans+1; } void updateM(int i, int value)//维护LIS的长度 { for(;i<=N;i+=lowbit(i)) if(value>B[i]) B[i]=value; } int getM(int i){//i代表位置,往前找最大的长度,i位置的数肯定可以使长度加1 int ans=0; for (;i>0;i-=lowbit(i)) if(B[i]>ans)ans=B[i]; return ans; } int main() { int t; int i,j,k,g=1; scanf("%d",&t); while(t--) { scanf("%d",&N); memset(B,0,sizeof(int)*(N+1)); for(i=1;i<=N;i++) { scanf("%d",&pos[i]); update(i,1); }//初始时有n个空位,从后往前插入 for(i=N;i>=1;i--) { pos[i]=getK(pos[i]+1);//第pos[i]+1个空位的位置 update(pos[i],-1); } int ans=0; printf("Case #%d:\n",g++); memset(B,0,sizeof(int)*(N+1)); for(i=1;i<=N;i++) { int len=getM(pos[i]); if(len+1>ans)ans=len+1; printf("%d\n",ans); updateM(pos[i],len+1); }puts(""); } return 0; }
