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】动物园的更多相关文章

  1. 洛谷P2375 动物园

    我要死了.这是我做过的最恶心的题之一. 天下第一的大毒瘤.有gay毒. 我不如熊猫好多年... 题意:给定字符串,求g[i],表示:[0, i]中满足该子串既是前缀又是后缀还不重叠的子串数. 解:题面 ...

  2. 洛谷 P2375 动物园

    题目详情 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法 ...

  3. P2375 动物园

    入口 题目的大意就是输出以任意一个字符结尾,既是前缀,又是后缀,且长度不超过总长度的一半的方案书的乘积. 考虑使用kmp 在处理失配数组的同时,处理出来以每个字符结尾的时的,能有多少个前缀和后缀相同的 ...

  4. Border Theory

    持续更新中!!!更个屁,无线停更! 前言: KMP 学傻了,看 skyh 说啥 border 树,跑来学 border 理论 洛谷云剪切板:https://www.luogu.com.cn/paste ...

  5. 【border相关】【P3426】 [POI2005]SZA-Template

    [border相关][P3426] [POI2005]SZA-Template Description 给定一个字符串 \(S\),要求一个最短的字符串 \(T\),使得 \(S\) 可以由 \(T\ ...

  6. 51nod1600 Simple KMP

    题目描述 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i) 显然对于一个字符串,如果我们将每个0<=i<=|S|看 ...

  7. 模板库 ~ Template library

    TOC 建议使用 Ctrl+F 搜索 . 目录 小工具 / C++ Tricks NOI Linux 1.0 快速读入 / 快速输出 简易小工具 无序映射器 简易调试器 文件 IO 位运算 Smart ...

  8. 洛谷 P2375 [NOI2014]动物园 解题报告

    P2375 [NOI2014]动物园 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定 ...

  9. VIJOS P1081 野生动物园 SBT、划分树模板

    [描述] cjBBteam拥有一个很大的野生动物园.这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子.这些狮子从北到南编号为1,2,3,…,N.每头狮子都有 ...

随机推荐

  1. Windows安装Nginx需要注意的地方

      在使用 Nginx 之前,首先要三连问,它是什么?用来做什么?为什么用它? 这篇文章很好的解答了上面的问题,并补充了什么是正向代理和反向代理以及区别的知识 https://www.cnblogs. ...

  2. StuQ技能图谱

  3. scrapy 使用

    启动方式: 写一个启动文件,与配置文件同级   from scrapy.cmdline import execute import sys,os sys.path.append(os.path.dir ...

  4. 【CTS2019】随机立方体(容斥)

    [CTS2019]随机立方体(容斥) 题面 LOJ 洛谷 题解 做这道题目的时候不难想到容斥的方面. 那么我们考虑怎么计算至少有\(k\)个极大值的方案数. 我们首先可以把\(k\)个极大值的位置给确 ...

  5. ASP.NET Core 应用程序状态

    在ASP.NET Core中,由多种途径可以对应用程序状态进行管理,使用哪种途径,由检索状态的时机和方式决定. 应用程序状态指的是用于描述当前状况的任意数据.包括全局和用户特有的数据. 开发人员可以根 ...

  6. jenkins 配置ssh remotes 报Failed to authenticate with public key

    问题:jenkins配置ssh远程连接时候报 ERROR: Failed to authenticate with public key com.jcraft.jsch.JSchException: ...

  7. SpringBoot静态资源文件

    1.默认静态资源映射 Spring Boot对静态资源映射提供了默认配置 Spring Boot默认将 /** 所有访问映射到一下目录 classpath:/static classpath:/pub ...

  8. OO第四单元作业小结

    一.本单元两次作业的架构设计 1.第一次作业 整体思路:以class为核心,建立MyInterface.MyAttribute.MyOperation.MyAssociation四个类分别储存每个类的 ...

  9. android开发中json与java对象相互转换

    json与java对象的相互转换.(使用com.google.gson) 在Android开发过程中,客户端总是需要从服务器获取数据,包括XML和json格式,目前json格式的数据使用较为普遍,所以 ...

  10. 移动4G插卡注网

    本文根据插入移动4G单卡到注册4G网络过程的mtklog分析. 插卡动作: 从以上信息无法区分单卡还是双卡,通过ATR参数判断: 注网流程,此过程未开启4G数据连接: [MS->NW] ESM_ ...