【bzoj3173】: [Tjoi2013]最长上升子序列
2016-02-25 10:28
543 查看
ms是个简单的splay+nlogn的最长上升子序列。。?
但是我老是搞不清顺序怎么办0.0
根据题目加入的顺序发现的性质要注意阿0.0
orzorzlyh
但是我老是搞不清顺序怎么办0.0
根据题目加入的顺序发现的性质要注意阿0.0
orzorzlyh
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=200011; const int inf=0x3f3f3f3f; struct node{int l,r,fa,size,mx,ans;}sp ; int root,cnt; int a ,dp ,ans ; //max的方法不太对。。。 void update(int x) { int l=sp[x].l,r=sp[x].r; sp[x].size=sp[l].size+sp[r].size+1; } void zig(int x) { int y=sp[x].fa; sp[y].l=sp[x].r; if(sp[x].r)sp[sp[x].r].fa=y; sp[x].fa=sp[y].fa; if(sp[y].fa) if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x; else sp[sp[y].fa].r=x; sp[x].r=y,sp[y].fa=x; update(y); } void zag(int x) { int y=sp[x].fa; sp[y].r=sp[x].l; if(sp[x].l)sp[sp[x].l].fa=y; sp[x].fa=sp[y].fa; if(sp[y].fa) if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x; else sp[sp[y].fa].r=x; sp[x].l=y,sp[y].fa=x; update(y); } void splay(int x,int aim) { while(sp[x].fa!=aim) { int y=sp[x].fa; if(sp[y].fa==aim) { if(sp[y].l==x)zig(x); else zag(x); } else { if(sp[sp[y].fa].l==y) { if(sp[y].l==x)zig(y),zig(x); else zag(x),zig(x); } else { if(sp[y].r==x)zag(y),zag(x); else zig(x),zag(x); } } } if(aim==0)root=x; update(x); } int find(int x,int wz) { if(x==0)return -1; int l=sp[x].l,r=sp[x].r; if(sp[l].size>=wz)return find(l,wz); if(sp[l].size+1>=wz)return x; return find(r,wz-sp[l].size-1); } int getnext(int x) { x=sp[x].r; while(sp[x].l)x=sp[x].l; return x; } void insert(int wz) { int x=find(root,wz-1); splay(x,0); int y=getnext(x); splay(y,x); sp[y].l=++cnt; sp[cnt].fa=y; sp[cnt].size=1; update(y); update(x); } void bili() { root=1; cnt=2; sp[1].r=2,sp[2].fa=1; sp[1].size=2;sp[2].size=1; } void dfs(int x) { if(x==0)return; dfs(sp[x].l); a[++cnt]=x; dfs(sp[x].r); } int main() { int n;cin>>n; bili(); for(int i=1;i<=n;i++) { int wz; scanf("%d",&wz);wz+=2; insert(wz); } cnt=0;dfs(root); for(int i=1;i<=n;i++) a[i]=a[i+1],dp[i]=inf; for(int i=1;i<=n;i++) { int j=lower_bound(dp+1,dp+1+n,a[i])-dp; dp[j]=a[i]; ans[a[i]-2]=j; } for(int i=1;i<=n;i++) { ans[i]=max(ans[i],ans[i-1]); printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- 【小镇的技术天梯】Linux shell的标准输入、输出和错误
- UVA1629Cake slicing(记忆化搜索)
- Yii2.0学习资源
- Python 第六篇(下):面向对象编程高级篇
- 融云SDK:获取用户Token的方法
- layoutsubviews什么时候调用
- 最新 face tracking成果
- 关于cxf 连.net 的webservice生成客户端异常( undefined element declaration 's:schema')
- 【C++】获得窗口和控件的句柄
- 144. Binary Tree Preorder Traversal
- 【.Net码农】网上常用免费WebServices集合
- JAVA实操:[1]数组习题
- javascript原生dom操作方法
- 【C++】二维数组的初始化
- 解决Apple World Wide Developer Relations Certificate Authority证书过期
- Struts2 自定义下拉框Tag标签
- 数据库索引浅析(一)
- makefile的语法及写法
- iOS 支付宝好友分享
- Java基础:Day02笔记内容 (常量、注释、变量)