TJOI2013(BZOJ3173)最长上升子序列
传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3173
做法:用Splay维护数列,nlogn求出LIS,最后再整理下答案即可
Codes:
1 #include<set> 2 #include<queue> 3 #include<vector> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 const int N = 100010; 11 #define fa(i) (T[i].p) 12 #define L(i) (T[i].s[0]) 13 #define R(i) (T[i].s[1]) 14 #define Key (L(R(root))) 15 #define Loc(i) (T[fa(i)].s[1]==i) 16 #define For(i,n) for(int i=1;i<=n;i++) 17 #define Rep(i,l,r) for(int i=l;i<=r;i++) 18 #define Down(i,r,l) for(int i=r;i>=l;i--) 19 #define sets(a,b,c) {if(a) T[a].s[c] = b;if(b) fa(b)= a;} 20 struct splay{ 21 int size,v,s[2],p; 22 void Sets(int x,int y){ 23 v = x; p = y; size = 1; 24 } 25 }T[N]; 26 27 struct TEMP{ 28 int id,ans; 29 }helps[N]; 30 int root = 1,A[N],tot,Q[N],ans,Ans[N]; 31 32 void Update(int i){ 33 T[i].size = T[L(i)].size + T[R(i)].size + 1; 34 } 35 36 void Rot(int x){ 37 int y = fa(x) , z = fa(y); 38 int lx = Loc(x) , ly = Loc(y); 39 sets(y,T[x].s[!lx],lx); 40 sets(z,x,ly); 41 sets(x,y,!lx); 42 Update(y); 43 } 44 45 void Splay(int i,int goal){ 46 while(fa(i)!=goal){ 47 if(fa(fa(i))!=goal) Rot(fa(i)); 48 Rot(i); 49 } 50 Update(i); 51 if(!goal) root = i; 52 } 53 54 int Rank(int kth,int i){ 55 if(T[L(i)].size+1==kth) return i; 56 else if(T[L(i)].size >= kth) return Rank(kth,L(i)); 57 else return Rank(kth-T[L(i)].size-1,R(i)); 58 } 59 60 int n,pos; 61 void init(){ 62 scanf("%d",&n); 63 T[root].size = 1;R(root) = 2;T[R(root)].size = 1; 64 sets(root,R(root),1);Key = tot = 3; 65 T[Key].size = 1;T[Key].v = 1;T[Key].p = R(root); 66 Update(R(root));Update(root);scanf("%d",&pos); 67 Rep(i,2,n){ 68 scanf("%d",&pos);pos++; 69 Splay(Rank(pos,root),0); 70 Splay(Rank(pos+1,root),root); 71 Key=++tot;T[Key].v = i;T[Key].size = 1;T[Key].p = R(root); 72 Update(R(root));Update(root); 73 } 74 } 75 76 void Visit(int i,int rank){ 77 if(L(i)) Visit(L(i),rank); 78 rank+=T[L(i)].size + 1; 79 if(rank!=1) A[rank-1] = T[i].v; 80 if(R(i)) Visit(R(i),rank); 81 } 82 83 bool cmp(TEMP A,TEMP B){ 84 return A.ans > B.ans; 85 } 86 87 int main(){ 88 //freopen("ans.out","w",stdout); 89 init(); 90 Visit(root,0); 91 int ans = 0; 92 For(i,n){ 93 if(Q[ans]<A[i]) { 94 Q[++ans] = A[i];Ans[i] = ans; 95 } 96 else{ 97 int L = 1 , R = ans; 98 while(R-L>1){ 99 int Mid = (L+R)>>1; 100 if(Q[Mid]>A[i]) R = Mid; 101 else L = Mid; 102 } 103 if(Q[L]>A[i]){ 104 Q[L] = A[i];Ans[i] = L; 105 } 106 else{ 107 Q[R] = A[i];Ans[i] = R; 108 } 109 } 110 } 111 For(i,n){ 112 helps[i].id = A[i]; 113 helps[i].ans = Ans[i]; 114 } 115 sort(helps+1,helps+n+1,cmp); 116 int j = 1; 117 Down(i,n,1){ 118 while(i<helps[j].id) j++; 119 Ans[i] = helps[j].ans; 120 } 121 For(i,n) printf("%d\n",Ans[i]); 122 return 0; 123 }