AmazingCounters.com

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 }

 

posted @ 2014-08-06 23:06  ZJDx1998  阅读(189)  评论(0编辑  收藏  举报