意甲冠军:

特定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的更多相关文章

  1. HdU 4046 Panda 段树

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4046 意甲冠军:到了bw组成的长度为n的字符串(n<=50000).有m次操作(m<=1000 ...

  2. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

  3. hdu 1542 Atlantis(段树&amp;扫描线&amp;面积和)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. HDU 4417-Super Mario-线段树+离线

    Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability ...

  5. HDU 3333-Turing Tree-线段树+离散+离线

    Description After inventing Turing Tree, 3xian always felt boring when solving problems about interv ...

  6. hdu 1542 Atlantis 段树区,并寻求,,,尼玛真坑人数据,不要打开一小阵!

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. HDU 1394 Minimum Inversion Number (数据结构-段树)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  8. HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)

    6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...

  9. HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)

    6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...

随机推荐

  1. hdu(预处理+线段树)

    给n个数,m个询问, 问任意区间内与其它数互质的数有多少个 比如3个数1 2 4,询问[1,3] 那么答案是1 千万要记住,这样的题目,如果你不转变下,使劲往线段树想(虽然转变之后,也说要用到线段树, ...

  2. Xamarin C# Android for Visual Studio 平台安装

    原文:Xamarin C# Android for Visual Studio 平台安装 Xamarin是基于Mono的平台,目前主要有以下产品(更具体请见:http://xamarin.com/pr ...

  3. Linux内核IP层的报文处理流程(一)

    本文主要讲解了Linux内核IP层的整体架构和对从网卡接受的报文处理流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式对Linxu内核中IP整体实现架构和对网卡 ...

  4. Android 动态显示和隐藏软键盘

    ** * 动态设置软盘的显示和隐藏 * @author JPH */ public class MainActivity extends Activity implements OnClickList ...

  5. poj1185炮兵阵地

    #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> ...

  6. Ubuntu下轻松切换GDM, LightDM , KDM

    如果已经安装LightDM和GDM登录显示器.那么在Ubuntu下怎么在各种DM间任意切换呢? 举例: 以切换到GDM为例,打开终端,使用命令: sudo dpkg-reconfigure gdm 接 ...

  7. Matlab绘图-很详细,很全面

    强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到 所需图形,这类函数称为高层绘图函数.此外,Matlab还提供 ...

  8. 新书《iOS8 Swift编程指南》货架

    颐和园的新书出版. 链接:http://www.amazon.cn/dp/B00YOQSYAO 这本书从去年开始7可能开始写.今年1完成这个月的第一稿,经过多次修改,今天,最后的正式出版,欢迎大家指正 ...

  9. Thinkphp编辑器扩展类kindeditor用法

    一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...

  10. PIC16SCM设置不同IO功耗端口状态的影响

    最近做的PIC低功耗微控制器,因此,要设置不同的IO端口状态有关电源的情况测试,在系列万用表的方法来测量电流,供应链管理IO港是在地狱,无头整个系统驱动器.的是PIC16F690单片机. 思路例如以下 ...