bzoj 3173: [Tjoi2013]最长上升子序列
这个题一开始感觉是想的差不多了,,然而不知道为什么没继续想(貌似是没考虑到treap的插入改怎么搞之类的)
那么这个题直接蹩脚的用treap模拟一下插入,然后枚举答案,在序列里二分就好了,最后答案就是max(ans[i],ans[i-1])(后面肯定不能比前面小吧)
1 #include <bits/stdc++.h> 2 #define LL long long 3 #define inf 0x3f3f3f3f 4 using namespace std; 5 inline int ra() 6 { 7 int x=0,f=1; char ch=getchar(); 8 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 9 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 10 return x*f; 11 } 12 int n,sz,root,now,mx; 13 int mn[100005],ans[100005]; 14 int v[100005],size[100005],rnd[100005],ls[100005],rs[100005]; 15 void update(int x){size[x]=size[ls[x]]+size[rs[x]]+1;} 16 void rturn(int &x){int t=ls[x]; ls[x]=rs[t]; rs[t]=x; update(x); update(t); x=t;} 17 void lturn(int &x){int t=rs[x]; rs[x]=ls[t]; ls[t]=x; update(x); update(t); x=t;} 18 void insert(int &k, int x) 19 { 20 if (!k){ 21 k=++sz; size[k]=1; rnd[k]=rand(); 22 return; 23 } 24 size[k]++; 25 if (size[ls[k]]<x) 26 { 27 insert(rs[k],x-size[ls[k]]-1); 28 if (rnd[rs[k]]<rnd[k]) lturn(k); 29 } 30 else 31 { 32 insert(ls[k],x); 33 if (rnd[ls[k]]<rnd[k]) rturn(k); 34 } 35 } 36 void dfs(int x) 37 { 38 if (!x) return; 39 dfs(ls[x]); 40 v[++now]=x; 41 dfs(rs[x]); 42 } 43 void solve() 44 { 45 memset(mn,127,sizeof(mn)); 46 mn[0]=-inf; 47 for (int i=1; i<=n; i++) 48 { 49 int t=upper_bound(mn,mn+mx+1,v[i])-mn; 50 if (mn[t-1]<=v[i]) 51 { 52 mn[t]=min(mn[t],v[i]); 53 ans[v[i]]=t; 54 mx=max(t,mx); 55 } 56 } 57 } 58 int main(int argc, char const *argv[]) 59 { 60 n=ra(); 61 for (int i=1; i<=n; i++) insert(root,ra()); 62 dfs(root); 63 solve(); 64 for (int i=1; i<=n; i++) 65 { 66 ans[i]=max(ans[i-1],ans[i]); 67 printf("%d\n",ans[i]); 68 } 69 return 0; 70 }