noip 模拟赛(by azui大爷) day2 t2(附O(1)求RMQ)
来源:互联网 发布:云安全软件好用吗 编辑:程序博客网 时间:2024/05/28 20:18
看到第三题是个毒瘤题,于是先来写下第二题的题解。
题意:给你一颗二叉树,要求在不改变其中序遍历的前提下,改变树的结构,
使新树前序遍历的字典序最小,输出这个前序遍历
题解:
表示好久都没有复习什么先序后序遍历了,结论什么的都忘干净了
于是这道题我直接输的12345……,还骗到20分。
这道题如果按照改变树的结构的思路来想的话,其实就是
AVL中的zig,zag操作,或者splay中的rotate,这样是可以做的
但是更简单的做法是分治,我们只需要在意中序遍历的顺序就可以了
显然我们可以将1作为根节点,那么现在,在中序遍历数组1左边的就
是目前的左子树,右边就是右子树,显然具有子性质,找到最小的编号
作为子树的根就可以了
这里额外需要做的是快速查找区间最小值,显然zkw线段树可以快速的
做到这一点,但是对于静态查询且不强制在线的话,是有nlogn预处理
O(1)查找的做法的:st表。 其实就是一个倍增
st[i][j]表示第j个节点到从第j个节点往后2^i个节点的最小值
(这个i,j位置有点别扭是因为说什么这样在预处理的时候上会快一点,但查询的时候会慢一点,玄学)
那么
st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))])(下面的st数组是存的下标,所以额外写了一个cmp)
查询(s,e)的时候,只需要稍微大于(e-s+1)/2且刚好是2的整数次幂的值
以s为起点取一段,再以e为终点取一段就可以了,不用去处理这两段重合
情况,因为最小值不会被影响
code:
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm> const int MAXN=100005;const int LOG=17;using namespace std;struct node{ int fa,lc,rc;}h[MAXN];int n,mcnt,M[MAXN]; bool f;int lg2[MAXN],st[LOG+5][MAXN]; inline void Read(int &Ret){ char ch;bool flag=0; for(;ch=getchar(),!isdigit(ch);)if(ch=='-')flag=1; for(Ret=ch-'0';ch=getchar(),isdigit(ch);Ret=Ret*10+ch-'0'); flag&&(Ret=-Ret);}void Get_Middle(int i){ if(!i) return; Get_Middle(h[i].lc); M[++mcnt]=i; Get_Middle(h[i].rc);}#define cmp(i,j) (M[i]<M[j]?i:j)inline int RMQ(int s,int e){ int t=lg2[e-s+1]; return cmp(st[t][s],st[t][e-(1<<t)+1]);}int Find_Front(int s,int e){ if(s>e) return 0; int t=RMQ(s,e); if(!f) printf("%d",M[t]),f=1; else printf(" %d",M[t]); Find_Front(s,t-1); Find_Front(t+1,e); return M[t];} inline void prepare(){ for(int i=2;i<=n;i++) lg2[i]=lg2[i>>1]+1; for(int i=1;i<=n;i++) st[0][i]=i; for(int i=1;i<=LOG;i++) for(int j=1;j+(1<<i)-1<=n;j++) st[i][j]=cmp(st[i-1][j],st[i-1][j+(1<<(i-1))]);}int main(){ Read(n); for(int i=1;i<=n;i++) { Read(h[i].lc); Read(h[i].rc); h[h[i].lc].fa=h[h[i].rc].fa=i; } int r=1; while(h[r].fa) r=h[r].fa; Get_Middle(r); prepare(); Find_Front(1,n); putchar(10);}
阅读全文
0 0
- noip 模拟赛(by azui大爷) day2 t2(附O(1)求RMQ)
- [DP] 计蒜客 2017 NOIP模拟赛(二)Day2 T2.紫色百合
- 【codevs 3289】[NOIP 2013 day2 T2] 花匠(dp)
- 【NOIP 2014 Day2 T2】寻找道路(BFS)
- 【NOIP 2011 Day2 T2】聪明的质检员(二分)
- NOIP模拟(10.19)T2 弹球
- NOIP模拟(20171023)T2 一样远
- NOIP模拟(10.23)T2 一样远
- NOIP模拟(10.24)T2 乘积
- NOIP模拟(20171024)T2 乘积
- NOIP模拟(20171026)T2 做运动
- NOIP模拟(10.26)T2 做运动
- NOIP模拟(10.30)T2 Game
- NOIP模拟(20171030)T2 游戏
- NOIP模拟(11.02)T2 最佳序列
- NOIP模拟(11.03)T2 排列
- NOIP模拟(11.06)T2 序列操作
- NOIP模拟(11.07)T2 路径统计
- 单链表的简单函数实现
- 【Python3.6爬虫学习记录】(四)爬取百度贴吧某帖子内容及图片
- HDU 1556-Color the ball(线段树区间更新)
- 构建降序的set
- 记一次springboot拦截器失效的调试
- noip 模拟赛(by azui大爷) day2 t2(附O(1)求RMQ)
- Java文件上传下载
- Python语法基础14.字符串
- 标志性log关键词
- R语言的基础函数操作
- 【CodeForces】616G
- hdu 3544 Alice's Game
- 驱动初学者的福利-从点亮led灯开始
- 测试中使用postman发送post、put请求