【border树】【P2375】动物园
Description
给定一个字符串 \(S\),对每个前缀求长度不超过该前缀一半的公共前后缀个数。
共有 \(T\) 组数据,每组数据的输出是 \(O(1)\) 的。
Limitations
\(1 \leq |S| \leq 10^6,~1 \leq T \leq 5\)
Solution
好水的NOI题
建出 \(border\) 树,对于树上每个节点,它的所有 \(border\) 与它的所有祖先一一对应。这是因为每个节点的父亲是它的最长 \(border\),数学归纳可以证明这个结论。
考虑对于这棵 \(border\) 树上任何一个节点到根的路径上节点的编号一定是单调减小的,这是因为每个结点的最长 \(border\) 显然小于自身。
因此,对于一个点 \(u\),如果 \(v\) 是一个合法的 \(border\),那么 \(v\) 的祖先一定是合法的 \(border\)。所以合法的 \(border\) 一定是一条以根为一个端点的链。
综合上面两条可以得出,如果 \(u\) 的合法 \(border\) 对应链的另一个端点为 \(v\),那么 \(u\) 的孩子的合法 \(border\) 的对应端点一定在 \(v\) 到 \(u\) 的路径上,因此这个端点位置是单调变深的。
所以只需要在 dfs 的时候维护根节点到该节点的链,并维护当前节点的答案位置即可。由于答案位置只会变大,因此答案位置的寻找是均摊 \(O(1)\) 的,暴力往下循环即可。
总时间复杂度 \(O(T |S|)\)。
Code
#include <cstdio>
#include <cstring>
#include <vector>
const int maxn = 1000006;
const int MOD = 1000000007;
int T;
int n, top;
ll ans;
char MU[maxn];
int border[maxn], pos[maxn], stack[maxn];
std::vector<int>son[maxn];
void KMP();
void clear();
int ReadStr(char *p);
void dfs(const int u);
int main() {
freopen("1.in", "r", stdin);
qr(T);
while (T--) {
clear();
n = ReadStr(MU + 1);
KMP();
for (int i = 1; i <= n; ++i) {
son[border[i]].push_back(i);
}
dfs(0);
qw(ans, '\n', true);
}
return 0;
}
int ReadStr(char *p) {
auto beg = p;
do *p = IPT::GetChar(); while ((*p > 'z') || (*p < 'a'));
do *(++p) = IPT::GetChar(); while ((*p >= 'a') && (*p <= 'z'));
*p = 0;
return p - beg;
}
void KMP() {
for (int i = 2, j = 0; i <= n; ++i) {
while (j && (MU[i] != MU[j + 1])) j = border[j];
if (MU[i] == MU[j + 1]) ++j;
border[i] = j;
}
}
void clear() {
ans = 1; top = -1;
for (auto &u : son) {
u.clear();
}
memset(pos, 0, sizeof pos);
}
void dfs(const int u) {
stack[++top] = u;
for (auto v : son[u]) {
int dv = v >> 1;
int &_ans = pos[v];
_ans = pos[u];
while ((_ans < top) && (stack[_ans + 1] <= dv)) ++_ans;
dfs(v);
}
if (pos[u]) {
(ans += pos[u] * ans) %= MOD;
}
--top;
}
【border树】【P2375】动物园的更多相关文章
- 洛谷P2375 动物园
我要死了.这是我做过的最恶心的题之一. 天下第一的大毒瘤.有gay毒. 我不如熊猫好多年... 题意:给定字符串,求g[i],表示:[0, i]中满足该子串既是前缀又是后缀还不重叠的子串数. 解:题面 ...
- 洛谷 P2375 动物园
题目详情 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法 ...
- P2375 动物园
入口 题目的大意就是输出以任意一个字符结尾,既是前缀,又是后缀,且长度不超过总长度的一半的方案书的乘积. 考虑使用kmp 在处理失配数组的同时,处理出来以每个字符结尾的时的,能有多少个前缀和后缀相同的 ...
- Border Theory
持续更新中!!!更个屁,无线停更! 前言: KMP 学傻了,看 skyh 说啥 border 树,跑来学 border 理论 洛谷云剪切板:https://www.luogu.com.cn/paste ...
- 【border相关】【P3426】 [POI2005]SZA-Template
[border相关][P3426] [POI2005]SZA-Template Description 给定一个字符串 \(S\),要求一个最短的字符串 \(T\),使得 \(S\) 可以由 \(T\ ...
- 51nod1600 Simple KMP
题目描述 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i) 显然对于一个字符串,如果我们将每个0<=i<=|S|看 ...
- 模板库 ~ Template library
TOC 建议使用 Ctrl+F 搜索 . 目录 小工具 / C++ Tricks NOI Linux 1.0 快速读入 / 快速输出 简易小工具 无序映射器 简易调试器 文件 IO 位运算 Smart ...
- 洛谷 P2375 [NOI2014]动物园 解题报告
P2375 [NOI2014]动物园 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定 ...
- VIJOS P1081 野生动物园 SBT、划分树模板
[描述] cjBBteam拥有一个很大的野生动物园.这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子.这些狮子从北到南编号为1,2,3,…,N.每头狮子都有 ...
随机推荐
- unity资源机制(转)
原文地址:https://www.jianshu.com/p/ca5cb9d910c0作者:重装机霸 2.资源概述 Unity必须通过导入将所支持的资源序列化,生成AssetComponents后,才 ...
- java中需要转义的特殊字符
在Java中,不管是String.split(),还是正则表达式,有一些特殊字符需要转义, 这些字符是 ( [ { / ^ - $ ¦ } ] ...
- Spring Boot 如何干掉 if else?
需求 这里虚拟一个业务需求,让大家容易理解.假设有一个订单系统,里面的一个功能是根据订单的不同类型作出不同的处理. 订单实体: service接口: 传统实现 根据订单类型写一堆的if else: 策 ...
- 【BZOJ4944】[NOI2017]泳池(线性常系数齐次递推,动态规划)
[BZOJ4944][NOI2017]泳池(线性常系数齐次递推,动态规划) 首先恰好为\(k\)很不好算,变为至少或者至多计算然后考虑容斥. 如果是至少的话,我们依然很难处理最大面积这个东西.所以考虑 ...
- 安装mysql驱动程序
1. MYSQL驱动:https://dev.mysql.com/downloads/connector/odbc/ 64 位版本:https://cdn.mysql.com//Downloads/ ...
- C# 随笔写txt
public static void WriterFile(string file) { string path = AppDomain.CurrentDomain.BaseDirectory; // ...
- jdk8 接口的变化
在jdk8之前,interface之中可以定义变量和方法,变量必须是public.static.final的,方法必须是public.abstract的.由于这些修饰符都是默认的以下写法等价 publ ...
- Spring @Import注解源码解析
简介 Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内.而在Spring 3.0之后提供了JavaConfig的方式,也就是将IO ...
- LIBRARY_PATH和LD_LIBRARY_PATH
LIBRARY_PATH是编译时指定的路径. LD_LIBRARY_PATH是运行时指定的动态链接库所在目录. 在运行一个可执行文件之前,可以通过ldd a.exe命令查看a.exe所依赖的动态链接库 ...
- android studio学习----Warning:Unable to find optional library: org.apache.http.legacy
主要是没有 android-23的版本 1.导入工程以后 Error:Could not find com.Android.tools.build:gradle:1.3.1. Searched in ...