HDU 4125 Moles 段树+KMP
意甲冠军:
特定n,
下面是一个1-n该装置。
下面的二进制字符串。
按给定的建立二叉树安排。
然后遍历树(根->左子树->根->右子树->根)
当遍历节点 如果右值为奇数入栈一个1,若为偶数入栈一个0
得到一个母串。
问母串中出现了几次子串。
思路:
先是建树得到母串。然后求子串个数就是裸的KMP。
建树就是找个规律,然后用线段树维护一下输入的排列
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long ll;
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
//
const int N = 600000+5;
const int M = 70000+5;
int mi[N<<2], pos[N];
inline void up(int& fa, int& ls, int& rs) {
if (ls>rs)
fa = rs;
else
fa = ls;
}
void build(int l, int r, int rt) {
if (l == r) {
mi[rt] = pos[l];
} else {
int mid = (l+r)>>1;
build(lson);
build(rson);
up(mi[rt], mi[rt<<1], mi[rt<<1|1]);
}
}
int query(int L, int R, int l, int r, int rt) {
if (L<= l && r<=R) {
return mi[rt];
} else {
int mid = (l+r)>>1;
if (L>mid)
return query(L, R, rson);
else if (R<=mid)
return query(L, R, lson);
else
return min(query(L, mid, lson), query(mid+1, R, rson));
}
}
void update(int p, int v, int l, int r, int rt) {
if (l == r) {
mi[rt] = v;
} else {
int mid = (l+r)>>1;
if (p <= mid)
update(p, v, lson);
else
update(p, v, rson);
up(mi[rt], mi[rt<<1], mi[rt<<1|1]);
}
} int T = 0, n, a[N], L[N], R[N];
char s[M], ch[N*3];
int nex[M], top;
void dfs(int u, int l, int r) {
update(u, n+1, 1, n, 1);
int v = query(l, u, 1, n, 1);
if (v != n+1) {
L[u] = a[v];
dfs(a[v], l, u);
}
v = query(u, r, 1, n, 1);
if (v != n+1) {
R[u] = a[v];
dfs(a[v], u, r);
}
}
void f(int u) {
char c;
if (u&1)
c = '1';
else
c = '0';
ch[top++] = c;
if (L[u] != -1) {
f(L[u]);
ch[top++] = c;
}
if (R[u] != -1) {
f(R[u]);
ch[top++] = c;
}
}
void work() {
int v, len, idx, ans = 0;
rd(n);
for (int i = 1; i <= n; ++i) {
rd(a[i]);
pos[a[i]] = i;
}
build(1, n, 1);
memset(L, -1, sizeof L);
memset(R, -1, sizeof R);
dfs(a[1], 1, n);
//
scanf("%s", s);
len = strlen(s);
nex[0] = nex[1] = 0;
for (int i = 1; i < len; ++i) {
int j = nex[i];
while (j && s[j] != s[i])
j = nex[j];
if (s[i] == s[j])
nex[i+1] = j+1;
else
nex[i+1] = 0;
}
//
top = 0;
f(a[1]);
idx = 0;
for (int i = 0; i < top; ++i) {
while (idx && s[idx] != ch[i])
idx = nex[idx];
if (s[idx] == ch[i])
++ idx;
if (idx == len) {
++ ans;
idx = nex[idx];
}
}
printf("Case #%d: %d\n", ++T, ans);
}
int main() {
int cas;
scanf("%d", &cas);
while (cas-->0)
work();
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
HDU 4125 Moles 段树+KMP的更多相关文章
- HdU 4046 Panda 段树
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4046 意甲冠军:到了bw组成的长度为n的字符串(n<=50000).有m次操作(m<=1000 ...
- HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板
好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...
- hdu 1542 Atlantis(段树&扫描线&面积和)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4417-Super Mario-线段树+离线
Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability ...
- HDU 3333-Turing Tree-线段树+离散+离线
Description After inventing Turing Tree, 3xian always felt boring when solving problems about interv ...
- hdu 1542 Atlantis 段树区,并寻求,,,尼玛真坑人数据,不要打开一小阵!
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1394 Minimum Inversion Number (数据结构-段树)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)
6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...
- HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)
6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...
随机推荐
- ZOJ 2110 Tempter of the Bone(条件迷宫DFS,HDU1010)
题意 一仅仅狗要逃离迷宫 能够往上下左右4个方向走 每走一步耗时1s 每一个格子仅仅能走一次且迷宫的门仅仅在t时刻打开一次 问狗是否有可能逃离这个迷宫 直接DFS 直道找到满足条件的路径 ...
- 宏碁宣布Liquid Jade智能机和Leap袖口
据科技网站Android Community 4月29日覆盖,宏碁29公布的新智能机Liquid Jade而随着智能手镯部署Liquid Leap.尽管宏碁已经宣布了一项新的外部基本信息.但价格格和商 ...
- 尺取法 poj3061 poj3320
尺取法就是反复推进区间的开头和结尾,来求满足条件的最下区间. poj3061 http://poj.org/problem?id=3061 给定一个都是正整数的序列,要我们求总和不小于S的连续子序列的 ...
- JavaScript 内存
JavaScript 中对内存的一些了解 在使用JavaScript进行开发的过程中,了解JavaScript内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么,也能够提高项目 ...
- linux 经常使用配置
教研室用的非常旧的fedora14,装一些软件和下载东西的时候比較蛋疼,恰巧ubuntu14.04 公布,于是安装试试,顺便记录下经常使用的配置,备忘. 1. 制作镜像,比較老的主板,写入方式选择US ...
- 询url包括字符串参数(js高度注意事项)
以防万一 url="http://write.blog.csdn.net/postedit? id=5&search=ok" function getArgs() { v ...
- 创Wcf案例数据服务
首先,创建实体类: using System; using System.Linq; using System.Collections.Generic; using System.Data.Servi ...
- jvisualvm远程监控Tomcat
网上已经有很多这方面的资料,但有些很杂乱,这里做了整理总结. 一.Java VisualVM 概述 对于使用命令行远程监控jvm 太麻烦 . 在jdk1.6 中 Oracle 提供了一个新的可视化的. ...
- JSP简单的练习-用户登记表
<%@ page language="java" import="java.util.*" pageEncoding="gb2312" ...
- hdu 5094 Maze(水搜索)
题目意思:说有一个人在(1,1) 他的目标点在(n,m) 每次是4方向的移动: 限制条件:有的各自之间有墙 或者门,强不可通过,有对应的要钥匙可以开启这个类型的所有门: 问题:求最少步骤数(和): 类 ...