bzoj3173 [Tjoi2013]最长上升子序列
乍看无思路。
注意插入的是按顺序的1~n的n个数。
假设我们已经插入完毕了;
1.对于数k,序列中比k大的数一定比k后插入!
2.对于数k,序列中在k左边比k大的数一定不影响以k结尾的最长上升子序列的长度!
那么:直接求以一个数结尾的最长上升子序列长度就好啦!!!(二分优化LIS 复杂度:O(log2n))
至于怎么处理出插入完毕后的序列:treap
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 cint inf=2147483647; 27 void inin(int &ret) 28 { 29 ret=0;int f=0;char ch=getchar(); 30 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 31 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 32 ret=f?-ret:ret; 33 } 34 int ch[100010][2],r[100010],s[100010],ed,root; 35 void maintain(int k){if(k)s[k]=1+s[ch[k][0]]+s[ch[k][1]];} 36 void rotate(int &k,int d){int p=ch[k][d^1];ch[k][d^1]=ch[p][d],ch[p][d]=k;maintain(k),maintain(p);k=p;} 37 void add(int &k,int x) 38 { 39 if(!k) 40 { 41 k=++ed;s[k]=1;r[k]=rand(); 42 return ; 43 } 44 s[k]++; 45 if(s[ch[k][0]]<x) 46 { 47 add(ch[k][1],x-s[ch[k][0]]-1); 48 if(r[ch[k][1]]<r[k])rotate(k,0); 49 } 50 else 51 { 52 add(ch[k][0],x); 53 if(r[ch[k][0]]<r[k])rotate(k,1); 54 } 55 } 56 int a[100010],tot; 57 void dfs(int x) 58 { 59 if(!x)return ; 60 dfs(ch[x][0]); 61 a[++tot]=x; 62 dfs(ch[x][1]); 63 } 64 int b[100010],ans[100010],Max; 65 int CSC() 66 { 67 int n; 68 inin(n); 69 re(i,1,n){int x;inin(x);add(root,x);} 70 dfs(root); 71 Clear(b,127); 72 b[0]=-inf; 73 for(int i=1;i<=n;i++) 74 { 75 int t=upper_bound(b,b+Max+1,a[i])-b; 76 if(b[t-1]<=a[i]) 77 { 78 b[t]=min(b[t],a[i]); 79 ans[a[i]]=t; 80 Max=max(t,Max); 81 } 82 } 83 re(i,1,n) 84 { 85 ans[i]=max(ans[i],ans[i-1]); 86 printf("%d\n",ans[i]); 87 } 88 return 0; 89 }