Moles(笛卡尔树 Z Algorithm)
original link - http://poj.org/problem?id=4005
题意:
有n个数,按照给出的顺序依次插入二叉搜索树,然后从小到大遍历(从根开始往下走,最后回来),路过的点值模2构成一个01序列 S S S,求这个序列中出现匹配串 T T T的次数。
解析:
可以分为两个问题:怎么构造出树的结构、怎么查询匹配串出现次数。
如果直接暴力查看是哪个点的儿子,一条链的情况下复杂度 O ( n 2 ) O(n^2) O(n2)。
开始的做法:
用set维护每个点的可以变为儿子的区间,插入时二分得到区间
\;
但是常数太大 T L E TLE TLE了。
后来发现了其中与笛卡尔树联系颇深,构造出来的树按序号看是小顶堆,按值看是二叉搜素树。
将其按照值排序后,再按照序号大小关系建笛卡尔树,就是正解了,时间复杂度 O ( n l o g n + n ) O(nlogn+n) O(nlogn+n)。
建好树后,得到字符串的过程,如果直接搜索会爆栈,改成栈模拟即可。
最后的过程比较简单,查看出现多少次,那么就是将 S , T → T S S,T\to TS S,T→TS,然后做一遍 Z A l g o r i t h m Z\;Algorithm ZAlgorithm,后面的每个位置匹配长度大于 ∣ T ∣ |T| ∣T∣就说明有一个。
代码:
/** Author : Jk_Chen* Date : 2019-10-05-12.07.13*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<set>
#include<stack>
#include<stdlib.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n';
const LL mod=1e9+7;
const int maxn=7e5+5;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/char x[maxn*5];
int len1,len;
int z[maxn*5];
void deal(){ // Z Algorithmmmm(z,0);int l=0,r=1;rep(i,1,len-1){if(r>i)z[i]=min(z[i-l],r-i);if(z[i]+i>=r){l=i,r=z[i]+i;while(r<len&&x[r]==x[r-l])r++;z[i]=r-l;}}z[0]=len;
}int son[maxn][2];
pill a[maxn];
bool vis[maxn];
int sta[maxn];
int rt;void init(int n){int top=0;rep(i,1,n){vis[i]=0;son[i][0]=son[i][1]=0;}rep(i,1,n){int lson=-1;while(top&&a[sta[top]].se>a[i].se)lson=sta[top],top--;if(top)son[sta[top]][1]=i;if(~lson)son[i][0]=lson;sta[++top]=i;}rep(i,1,n){vis[son[i][0]]=vis[son[i][1]]=1;}rep(i,1,n){if(!vis[i]){rt=i;break;}}
}void dfs(int p){stack<pill>S;S.push({p,1});while(!S.empty()){pill pi=S.top();S.pop();x[len++]='0'+pi.fi%2;if(pi.se){if(son[pi.fi][1]){S.push({pi.fi,0});S.push({son[pi.fi][1],1});}if(son[pi.fi][0]){S.push({pi.fi,0});S.push({son[pi.fi][0],1});}}}
}int main(){int t=rd,cas=0;while(t--){int n=rd;rep(i,1,n)a[i].fi=rd,a[i].se=i;sort(a+1,a+1+n);gets(x);len=len1=strlen(x);init(n);dfs(rt);x[len]='\0';
// puts(x);deal();int ans=0;rep(i,len1,len-1){if(z[i]>=len1)ans++;}printf("Case #%d: %d\n",++cas,ans);}
}
Moles(笛卡尔树 Z Algorithm)相关推荐
- HDU 4125 Moles 笛卡尔树 + kmp
题意:有n(1<=n<=600000)个鼹鼠挖洞,每个鼹鼠有给定权值,挖的洞是一颗二叉树(左边的鼹鼠权值都比当前鼹鼠小,右边的鼹鼠权值比当前鼹鼠大), 也要按照鼹鼠的出场顺序挖洞,在形成的 ...
- [线段树or笛卡尔树+简单KMP]poj4005 or hdu4125 Moles
题意:N只编号1-N的鼹鼠打洞,第i只编号为a[i],编号不重复.打的洞的样子符合以a[i]为值,以下标为插入顺序的二叉搜索树.现在从根出发,存在左子树则先走左子树,否则往右走,每经过一个洞(结点), ...
- YbtOJ#752-最优分组【笛卡尔树,线段树】
正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 nnn个人,每个人有cic_ici和did_idi分别表示这个人所在的队伍的最少/最多人数. 然后 ...
- P4755-Beautiful Pair【笛卡尔树,线段树】
正题 题目链接:https://www.luogu.com.cn/problem/P4755 题目大意 nnn个数字的一个序列,求有多少个点对i,ji,ji,j满足ai×aj≤max{ak}(k∈[l ...
- YbtOJ#20240-[冲刺NOIP2020模拟赛Day10]弱者对决【笛卡尔树,区间dp】
正题 题目链接:https://www.ybtoj.com.cn/contest/68/problem/4 题目大意 mmm个三元组(ai,bi,ci)(a_i,b_i,c_i)(ai,bi,ci ...
- 【笛卡尔树】【线段树】meetings 会议(P5044)
正题 P5044 题目大意 给出一个序列a,设 dist(x,y)=maxi=xyaidist(x,y)=\max_{i=x}^ya_idist(x,y)=maxi=xyai,有m个询问,对于每 ...
- [BZOJ]4199: [Noi2015]品酒大会(后缀数组+笛卡尔树)
Time Limit: 10 Sec Memory Limit: 512 MB Description Input Output Sample Input 10 ponoiiipoi 2 1 4 7 ...
- HDU - 6305 RMQ Similar Sequence(笛卡尔树)
http://acm.hdu.edu.cn/showproblem.php?pid=6305 题目 对于A,B两个序列,任意的l,r,如果RMQ(A,l,r)=RMQ(B,l,r),B序列里的数为[0 ...
- 洛谷 - P4755 Beautiful Pair(笛卡尔树+主席树)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,现在一个数对 ( i , j ) 如果满足 a[ i ] * a[ j ] <=max( a[ i ] ~ a[ j ] ),则称其 ...
最新文章
- 零基础入门--中文命名实体识别(BiLSTM+CRF模型,含代码)
- mysql的突然变成本地不能用密码,远程要用密码才能登录,这是神马情况???求解...
- 5个酷毙的Python神器工具
- angular2 组件交互
- 洛谷 - P3391 【模板】文艺平衡树(Splay-区间反转)
- 表单验证JavaScript实现正则匹配、随机验证码、密码强度、加拖拽加蒙板
- 在cygwin下编译c语言
- python multiprocessing 得到多进程返回的结果
- linux查看后台执行的所有任务与对应的命令
- mysql——启动服务问题Found option without preceding group in config file
- 入门Python,看这一篇就够了,史上最全的Python基础语法知识清单!
- Linux命令----系统目录结构
- 身份证阅读器读卡器React网页方法实现身份证的读取
- svn版本管理软件——svn分支管理
- 命令行字符界面与图形界面切换
- 开发历程:网页视频流媒体播放器EasyPlayer.JS开发web H5网页播放H.265视频支持FLV与HLS直播与点播
- excel锁定第一行_将Excel标题行锁定在适当的位置
- python 二维码生成器_python二维码生成器
- 什么是localhost(127.0.0.1)?
- goaheadlinux移植_goahead(嵌入式Web服务器)之交叉编译、移植篇
热门文章
- 两轮电动车被小米、哈啰们盯上了
- 终极事务处理(XTP,Hekaton)——万能大招?
- FCFS和SJF算法
- Unity Shader 实现简单的压扁效果
- char **argv什么意思呢
- 数据可视化——彩色通用设计之色彩搭配(制作对色盲人群友好的图形和演示)
- Android 一个简单手机响铃功能实现
- 揭开深度跟踪的力量--Unveiling the Power of Deep Tracking (ECCV2018)
- [Linux Shell] su和sudo命令
- java joda datetime_关于java:使用Joda将日期转换为DateTime