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]的时候,线段树对应的位置 ...
随机推荐
- w7关闭休眠增加C盘容量
http://jingyan.baidu.com/article/f3ad7d0fc0992e09c2345b51.html powercfg -h off,即可关闭休眠功能 powercfg -h ...
- 清除Android工程中没用到的资源(转)
项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理 ...
- POJ 3684 Priest John's Busiest Day 2-SAT+输出路径
强连通算法推断是否满足2-sat,然后反向建图,拓扑排序+染色. 一种选择是从 起点開始,还有一种是终点-持续时间那个点 開始. 若2个婚礼的某2种时间线段相交,则有矛盾,建边. easy出错的地方就 ...
- 在 树莓派上使用 c++ libsockets library
rpi默认安装的编译器是gcc-4.6.2 而现在最新的c++ libsockets library 需要使用支持c++-11特征的编译器,即需要4.8.2才可以.为此,需要先升级编译器才可以支持编译 ...
- Java Swing 绝对布局管理方法,null布局(转)
首先把相关容器的布局方式设为 setLayout(null); 然后调用组件的 setBounds() 方法 设置button的位置为(100,100) 长宽分别为 60,25 jButton.se ...
- Node.js Tools for Visual Studio
https://www.visualstudio.com/en-us/features/node-js-vs.aspx
- 调用CachedRowSetImpl类时,为什么会出现这样的错误
Access restriction: The type CachedRowSetImpl is not accessible due to restriction on required libra ...
- eclipse在maven项目交付svn忽略简介
文章来源:http://blog.csdn.net/chaijunkun/article/details/34805385,转载请注明. 不时因为它将有关鲍恩梳理,它会做出相应的内容不变.文. ecl ...
- 发现SQL Server惊天大秘密!!
原文:发现SQL Server惊天大秘密!! --set statistics xml onCREATE TABLE T_TEST(ID INT IDENTITY PRIMARY KEY,Create ...
- Block学习一门:基本使用,使用block包NSURLRequest异步请求
首先,看一下下面的代码: void (^myFirstBlock)(int theOne,int theTwo) = ^(int theOne,int theTwo){ NSLog(@"== ...