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]的时候,线段树对应的位置 ...
随机推荐
- cocos2d-x 3.2 它 三消游戏——万圣节大作战
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- J2SE基础:1.类和对象基础
什么是对象 在Java语言,全部的人,事物或者模块都是一个对象. 同样的对象具有一些同样的特性. 狗,猫,蛇3个对象(动物的对象) 苹果,梨,桔子3个对象(水果的对象) 什么是类 能够将现实生活中的对 ...
- 不root的情况下 查看App的数据表
一直以来查看sqlite的数据库都须要root才干查看,可是公司的好多測试机root起来比較麻烦~~~ 近期刚好项目上线,略闲, 于是决定写一个libraryproject便于以后调试代码 关键代码例 ...
- [转载]起动service保存android系统log( logcat服务)
原文链接:http://www.myexception.cn/android/1904013.html 启动service保存android系统log 作为android开发工程师,出现了BUG是否苦 ...
- WebPack实例与前端性能优化
[前端构建]WebPack实例与前端性能优化 计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给 ...
- 每天进步一点点——再次了解Linux进程ID
转载请注明出处:http://blog.csdn.net/cywosp/article/details/38968011 1. 概述 众所周知,进程(process)是一个可运行程序的实例,可是在Li ...
- 小米2S 中文和英文支持TWRP,真实双系统支持
经过我几天的努力小米2S的TWRP 的功能已经完美了. 支持功能 : 中文和英文显示能相互切换 真实双系统功能已经完成95%. 刷入手机方法.由于时间原因我只制作了img文件.没有制作成卡刷包格式. ...
- Java二叉排序树(转)
一.二叉排序树定义 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性 ...
- improper Advertising identifier [IDFA] Usage. Your app contains the Advertising Identifier [IDFA] AP
找到答案了.随便传个包上去.然后拒绝掉,又一次prepare to upload.就会出现选项. 相应选择就好了.
- Android研究之手PullToRefresh(ListView GridView 下拉刷新)使用具体解释
群里一哥们今天聊天偶然提到这个git hub上的控件:pull-to-refresh ,有兴趣的看下,样例中的功能极其强大,支持非常多控件.本篇博客具体给大家介绍下ListView和GridVi ...