【bzoj 3173】[Tjoi2013]最长上升子序列
Description
Input
Output
Sample Input
3
0 0 2
Sample Output
1
1
2
HINT
100%的数据 n<=100000
易得,令f[i]表示以数字i结尾的最长上升子序列长度,则新加入一个数时不会影响到其他的f[i]。
在线写法:用平衡树直接模拟,每一次用位置的前缀f[i]的最大值+1来作为当前的新加入的数的f[i],然后将其插入到指定位置。输出答案时直接查找当前所有f[i]的最大值。
离线写法:求出最终序列然后nlogn求一次LIS即可,可以用树状数组或平衡树实现。
【fhq-treap 在线】
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 const int N=1e5+5; 7 int n,root,cnt,rt1,rt2,pos,ch[N][6]; 8 #define lc ch][0 9 #define rc ch][1 10 #define rnd ch][2 11 #define sz ch][3 12 #define v ch][4 13 #define mx ch][5 14 int read() 15 { 16 int x=0,f=1;char c=getchar(); 17 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 18 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 19 return x*f; 20 } 21 void up(int w) 22 { 23 w[sz]=w[lc][sz]+w[rc][sz]+1; 24 w[mx]=max(w[lc][mx],w[rc][mx]); 25 w[mx]=max(w[mx],w[v]); 26 } 27 void split(int w,int& l,int& r,int k) 28 { 29 if(!w){l=r=0;return;} 30 int lson=w[lc][sz]; 31 if(k<=lson){r=w;split(w[lc],l,w[lc],k);} 32 else {l=w;split(w[rc],w[rc],r,k-lson-1);} 33 up(w); 34 } 35 int merge(int a,int b) 36 { 37 if(!a||!b)return a+b; 38 if(a[rnd]<b[rnd]){a[rc]=merge(a[rc],b);up(a);return a;} 39 else {b[lc]=merge(a,b[lc]);up(b);return b;} 40 } 41 void ins(int& w,int x,int k) 42 { 43 if(x[rnd]<w[rnd]||!w){split(w,x[lc],x[rc],k);w=x;up(w);return;} 44 int lson=w[lc][sz]; 45 if(k<=lson)ins(w[lc],x,k); 46 else ins(w[rc],x,k-lson-1); 47 up(w); 48 } 49 int query(int pos) 50 { 51 rt1=rt2=0;split(root,rt1,rt2,pos); 52 int ans=rt1[mx];root=merge(rt1,rt2); 53 return ans; 54 } 55 int main() 56 { 57 n=read(); 58 for(int i=1;i<=n;i++) 59 { 60 pos=read(); 61 cnt++;cnt[v]=query(pos)+1; 62 cnt[sz]=1;cnt[rnd]=rand(); 63 ins(root,cnt,pos); 64 printf("%d\n",root[mx]); 65 } 66 return 0; 67 }
View Code
【树状数组 离线】
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N=1e5+5; 6 int n,id,cnt,f[N],ans[N],a[N],num[N],bit[N]; 7 int read() 8 { 9 int x=0,f=1;char c=getchar(); 10 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 11 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 12 return x*f; 13 } 14 int lowbit(int x){return x&(-x);} 15 void ins(int x){while(x<=n)bit[x]--,x+=lowbit(x);} 16 int pos(int x) 17 { 18 int now=0,ans=0; 19 for(int i=17;i>=0;i--) 20 { 21 now+=(1<<i); 22 if(now<n&&ans+bit[now]<x)ans+=bit[now]; 23 else now-=(1<<i); 24 } 25 return now+1; 26 } 27 int main() 28 { 29 n=read(); 30 for(int i=1;i<=n;i++) 31 { 32 a[i]=read();bit[i]++; 33 if(i+lowbit(i)<=n)bit[i+lowbit(i)]+=bit[i]; 34 } 35 for(int i=n;i>=1;i--) 36 id=pos(a[i]+1),num[id]=i,ins(id); 37 for(int i=1;i<=n;i++) 38 { 39 id=lower_bound(f+1,f+cnt+1,num[i])-f; 40 if(id>cnt)f[++cnt]=num[i]; 41 else f[id]=num[i]; 42 ans[num[i]]=id; 43 } 44 for(int i=1;i<=n;i++)ans[i]=max(ans[i],ans[i-1]),printf("%d\n",ans[i]); 45 return 0; 46 }
View Code
转载于:https://www.cnblogs.com/zsnuo/p/7918389.html
【bzoj 3173】[Tjoi2013]最长上升子序列相关推荐
- BZOJ 3173: [Tjoi2013]最长上升子序列
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1524 Solved: 797 [Submit][ ...
- [BZOJ]3173: [Tjoi2013]最长上升子序列
题解: 考虑按照元素升序加入 所以对位置在其后的元素LIS无影响 然后从前面位置的最大值转移过来就行 ,,,,平衡树无脑模拟 #include <algorithm> #includ ...
- bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2051 Solved: 1041 [Submit] ...
- 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)
[题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...
- BZOJ3173 [TJOI2013]最长上升子序列
题面: 3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2108 Solved: 1067 [Sub ...
- [TJOI2013]最长上升子序列
[TJOI2013]最长上升子序列 题目大意: 给定一个序列,初始为空.将\(1\sim n(n\le10^5)\)的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字后输出LIS长 ...
- P4309 [TJOI2013]最长上升子序列 平衡树 + dp
传送门 文章目录 题意: 思路: 题意: 思路: 注意到一个很关键的条件,每次插入iii,而iii是递增的,也就是说插入iii之后只会从前面的最大值转移过来,所以我们现在只需要维护插入操作即可,这个显 ...
- [BZOJ3173][Tjoi2013]最长上升子序列
[BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...
- BZOJ3173:[TJOI2013]最长上升子序列(Splay)
Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一 ...
最新文章
- 名片识别信息分类python_python体验名片识别OCR
- layer弹出层扩展自定义样式
- 云端部署大数据解决方案该用IaaS还是PaaS?
- 微信自定义菜单java_使用Java语言开发微信公众平台(八)——自定义菜单功能
- 22.分布式系统基础设施
- C语言练习题,鸡兔同笼
- Cadence Orcad Capture原理图导出PDF图文视频教程
- CSS 网页弹出微信二维码
- 误差反向传播法实现手写数字识别(纯numpy实现)
- 【矩阵乘】【DP】【codevs 1305】Freda的道路
- 解决u盘图标显示异常
- PHP对接淘宝客api完成APP引流优惠券
- 海康iSecure Center 综合安防管理平台安装部署教程 - CentOS系统
- pr图形模板预设怎么使用_Pr 2017版本Premiere使用标题预设动态图形,提示要安装AE...
- 扫盲:回囙囜囝回囟因囡団囤囥囦囧囨囩囱囫…(认识吗?)
- 计算机网络第二章习题
- V4L2编程代码实现以及YUV格式(V4L2二)
- 10组团队项目-Alpha冲刺-6/6
- EmWin学习课堂_小白EmWin_EmWin快速入门_EmWin用Button控件显示文本
- Win10桌面我的电脑怎么调出来?最简单方法教学
热门文章
- 1044 火星数字 (20 分)(c++)
- 1030 完美数列 (25 分)(c语言)
- beanpostprocessor与@autowired的关系
- android 屏幕禁止,Android应用禁止屏幕休眠的几种方法
- 探究java-JVM的五步(三步)类加载机制(包含类加载过程的一些代码书写,如类加载代码)
- MCS-51单片机的指令时序
- 牛客-139 I. Substring(后缀数组 or 后缀自动机)
- allocator类初学的简单例子
- c++ 标准库中 cin.ignore()
- C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解