线段树+KMP-hdu-4125-Moles
来源:互联网 发布:2017java就业形势 编辑:程序博客网 时间:2024/05/19 16:02
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4125
题目意思:
给1~n组成的n个数,按输入顺序插入到平衡二叉树中,现在按1~n从小到大的顺序从根开始访问节点,每遇到一个节点i,如果i为奇数则序列+‘1’,如果i为偶数则序列+‘0’,这样得到一个序列res,给一个01序列s,求s在res中出现的次数,可以重叠。
解题思路:
首先要明白平衡二叉树的三个性质:
1、对于新插入的节点,其父亲要么是比自己大的最小的那个,或比自己小的最大的那个。
2、先序遍历为从小到大的顺序。
3、先序遍历回到根节点一共要访问2*n-1次节点。因为有n-1条边,一共有2*n-2个度,对于每个节点来说它的度数即为它的访问次数,而根节点进来的时候要加一个度,所以就是2*n-1次。
问题就转化成了,给一个数,求出在它之前的数序列中小于它的最大值或大于它的最小值。而这个问题可以用线段树维护,每个区间维护该区间已经放了数的最大值和最小值,如果查小于va的最大值,如果va>mid,则直接返回max(左区间的最大值,查右边)。同理查询大于va的最小值。
这个问题解决后,就是按先序顺序遍历,求出走的序列res.
最后KMP求出s在res中出现的次数,因为可以重复,所有每找到一个完全匹配串后,模式串下标跳到其的next值处。
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 610000int n;struct Inte{ int mi,ma; //线段树维护区间的最大值和最小值}inte[Maxn*4];struct Node //静态存储,左右孩子节点{ int l,r;}node[Maxn];void pushup(int v) //向上更新{ inte[v].mi=min(inte[v<<1].mi,inte[v<<1|1].mi); inte[v].ma=max(inte[v<<1].ma,inte[v<<1|1].ma);}void build(int l,int r,int rt){ if(l==r) //建树 { inte[rt].mi=INF; //把最小值置为无穷大,表示不存在 inte[rt].ma=0; //把最大值置为0 return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}void update(int l,int r,int rt,int va) //单点更新{ if(l==r) { inte[rt].mi=inte[rt].ma=va; return ; } int m=(l+r)>>1; if(va<=m) update(lson,va); else update(rson,va); pushup(rt);}int query1(int l,int r,int rt,int va) //查询小于va的最大值{ if(l==r) return inte[rt].ma; int m=(l+r)>>1; if(va<=m) //不需要查询右区间了 return query1(lson,va); else //左区间的直接返回后比较 return max(inte[rt<<1].ma,query1(rson,va));}int query2(int l,int r,int rt,int va)//查询大于va的最小值{ if(l==r) return inte[rt].mi; int m=(l+r)>>1; if(va<=m) return min(inte[rt<<1|1].mi,query2(lson,va)); else return query2(rson,va);}char res[Maxn<<1];int s,cnt;char bb[7500];void dfs(int cur) //按先序遍历搜{ res[++cnt]=(cur&1)?'1':'0'; //走到改点 if(node[cur].l) //如果有左儿子 { dfs(node[cur].l); if(node[cur].r) //如果有右儿子 { res[++cnt]=(cur&1)?'1':'0';//访问完左子树,回到它自己 dfs(node[cur].r); //再访问右子树 } res[++cnt]=(cur&1)?'1':'0';//回到自己 return ; } if(node[cur].r) //只有右子树 { dfs(node[cur].r); res[++cnt]=(cur&1)?'1':'0'; //访问完右子树后回到自己 }}int next[7500],nn;void getnext() //模式串求next数组{ int j=0; next[1]=0; for(int i=2;i<=nn;i++) { while(j>0&&bb[j+1]-bb[i]) j=next[j]; if(bb[j+1]==bb[i]) j++; next[i]=j; } return ;}int KMP() //{ int j=0; int ans=0; for(int i=1;i<=cnt;i++) { while(j>0&&bb[j+1]-res[i]) j=next[j]; if(bb[j+1]==res[i]) j++; if(j==nn) { ans++; j=next[j]; } } return ans;}int main(){ int t; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { scanf("%d",&n); build(1,n,1); //建树 scanf("%d",&s); update(1,n,1,s);//插到叶子 cnt=0; memset(node,0,sizeof(node)); for(int i=2;i<=n;i++) { int a,al,ar; scanf("%d",&a); al=query1(1,n,1,a); //小于a的最大值 ar=query2(1,n,1,a); //大于a的最小值 if(!al) //不存在小于a的最大值 node[ar].l=a; //那么只能是以大于a的最小值作为父亲 else if(ar==INF) //不存在自己作为左儿子的父亲 node[al].r=a; //那么只可能是自己是右儿子的父亲 else { if(node[al].r) //已经有了 node[ar].l=a; else node[al].r=a; } update(1,n,1,a);//加到线段树中 } /* for(int i=1;i<=n;i++) printf("i:%d l:%d r:%d\n",i,node[i].l,node[i].r);*/ cnt=0; dfs(s); scanf("%s",bb+1); nn=strlen(bb+1); getnext(); int ans=KMP(); printf("Case #%d: %d\n",ca,ans); } return 0;}
- 线段树+KMP-hdu-4125-Moles
- HDU 4125 Moles 线段树+KMP
- hdu Moles(线段树&KMP)
- HDU 4125 Moles 笛卡尔树 + kmp
- HDU 4125 Moles 树状数组 + KMP
- HDU 4125 Moles 二叉排序树 树状数组 kmp
- HDU_4125 Moles 线段树
- hdu 4125 Moles
- hdu 4763 Theme Section(扩展kmp+线段树)
- (线段树+kmp) 1828
- 【Hash\KMP\线段树】文明的复兴
- hdu 1754 线段树
- hdu 1754 线段树
- HDU 1698 线段树
- hdu 1754 线段树
- 【线段树】hdu 1754
- hdu-1166 线段树
- HDU-2688 线段树
- 什么是inf文件,inf运行安装方式,怎样双击运行inf文件
- 人物运动的demo
- 使用 Python 实现跨平台的安装程序
- Android webview 初略
- 断网或断电后,oracle不能正常连接
- 线段树+KMP-hdu-4125-Moles
- 越狱开发分享
- struts2值栈理解
- hdu1525 Euclid's Game
- 百度2014校园招聘技术类软件研发(济南站)一面总结
- linux 内核辅助接口
- JAVA网络编程TCP和UDP
- poj 1861 Network
- IO流简要概括