【[POI2006]OKR-Periods of Words】
很妙的一道题
感觉又加深了对\(KMP\)还有\(next\)数组的理解
先来看看这个鬼畜的题意,大致就是给你一个字符串,对于这个字符串的每一个前缀,要去找到这个前缀的一个最长的前缀,使得前缀成为这个前缀的前缀倍长之后的前缀
很蛇皮的题意,之后可能就会懵逼了,这根\(KMP\)有什么关系
我们来考虑这样一张图

那个标这黑点的部分是这个前缀\(i\)的\(next[i]\),于是我们如果将这个红色的部分倍长,这个相等的前缀和后缀就可以卡到一起了,于是就满足了前缀成为这个前缀的前缀倍长之后的前缀的要求
但是这显然不能够满足最长的前缀这个要求
很显然这个红色的前缀长度为\(i-next[i]\),如果这个红色的部分更短想让红色部分更长一些的话我们就得让\(next[i]\)变小
怎么让\(next[i]\)变小呢,很显然我们多跳几次\(next\)就好了,直到我们跳\(next\)跳不动了,那么我们就找到了最短的相等前缀和后缀,这个时候红色部分就是最长的了
所以我们可以写一个暴力跳\(next\)的代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
#define maxn 1000005
#define LL long long
char S[maxn];
int nx[maxn];
int n;
LL ans;
int main()
{
scanf("%d",&n);
scanf("%s",S+1);
nx[0]=nx[1]=0;
for(re int i=2;i<=n;i++)
{
int p=nx[i-1];
while(p&&S[p+1]!=S[i]) p=nx[p];
if(S[i]==S[p+1]) nx[i]=p+1;
else nx[i]=0;
}
for(re int i=1;i<=n;i++)
{
int p=nx[i];
if(!p) continue;
while(nx[p]) p=nx[p];
ans+=i-p;
}
printf("%lld",ans);
return 0;
}
显然暴力跳\(next\)很容易被卡成\(O(N^2)\),我们得有一个更妙的方法来得到一个前缀的最短非空相等前缀后缀
于是我们设\(num[i]\)表示\(i\)这个前缀的最短相等前缀后缀的长度
于是答案就是\(\sum_{i=1}^ni-num[i]\)
对于这个\(num\)数组我们还是可以在求\(next\)的时候顺便求出来
如果一个\(i\)和某个位置\(p+1\)匹配上了,那么\(num[i]=num[p+1]\)显然\(i\)最后跳下去也就是\(num[p+1]\)得到的最短相等前缀后缀
如果没有匹配上\(num[i]=i\),\(num\)等于自己
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
#define maxn 1000005
#define LL long long
char S[maxn];
int nx[maxn],num[maxn];
int n;
LL ans;
int main()
{
scanf("%d",&n);
scanf("%s",S+1);
nx[0]=nx[1]=0;
num[1]=1;
for(re int i=2;i<=n;i++)
{
int p=nx[i-1];
while(p&&S[p+1]!=S[i]) p=nx[p];
if(S[i]==S[p+1]) nx[i]=p+1,num[i]=num[p+1];
else nx[i]=0,num[i]=i;
}
for(re int i=2;i<=n;i++)
ans+=(i-num[i]);
printf("%lld",ans);
return 0;
}
【[POI2006]OKR-Periods of Words】的更多相关文章
- 【英语魔法俱乐部——读书笔记】 2 中级句型-复句&合句(Complex Sentences、Compound Sentences)
[英语魔法俱乐部——读书笔记] 2 中级句型-复句&合句(Complex Sentences.Compound Sentences):(2.1)名词从句.(2.2)副词从句.(2.3)关系从句 ...
- 【PY从0到1】 一文掌握Pandas量化基础
# 2[PY从0到1] 一文掌握Pandas量化基础 # Numpy和pandas是什么关系呢? # 在我看来,np偏向于数据细节处理,pd更偏向于表格整体的处理. # 要记住的pd内部的数据结构采用 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- 【Python五篇慢慢弹】数据结构看python
数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...
- 【十大经典数据挖掘算法】PageRank
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 我特地把PageRank作为[十大经 ...
- 【十大经典数据挖掘算法】EM
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 极大似然 极大似然(Maxim ...
- 【十大经典数据挖掘算法】AdaBoost
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 集成学习 集成学习(ensem ...
- 【十大经典数据挖掘算法】SVM
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...
- 【ASP.NET程序员福利】打造一款人见人爱的ORM(二)
上一篇我已经给大家介绍AntORM的框架[ASP.NET程序员福利]打造一款人见人爱的ORM(一),今天就来着重介绍一下如何使用这套框架 1>AntORM 所有成员 如果你只想操作一种数据库,可 ...
- 【bb平台刷课记】wireshark结合实例学抓包
[bb平台刷课记]wireshark结合实例学抓包 背景:本校形势与政策课程课需要在网上观看视频的方式来修得学分,视频网页自带"播放器不可快进+离开窗口自动暂停+看完一集解锁下一集(即不能同 ...
随机推荐
- 将JavaScript语句插入HTML文档
(1) 使用 <SCRIPT> 标签将语句嵌入文档 <script type="text/javascript"> function Que() { } & ...
- css兼容小问题
1.RGBA在CSS3.0体现,不向下兼容: 2.非float元素和float元素在一起版本时,非float元素会排斥float元素,为避免换行,float元素应优先显示(放非float元素之前)
- MDI-设置子窗体只能弹出一个--单例模式
不足之处,欢迎指正! 什么是MDI..我表示不知道的呢. MDI(Multiple Document Interface)就是所谓的多文档界面,与此对应就有单文档界面 (SDI), 它是微软公司从Wi ...
- MVC设计模式实现权限管理登录,超详细
功能实现:在页面输入给定的用户名之一,可以显示当前用户的权限,也可以在页面更改该用户的权限,更新之后保存.像下面这样. 填写用户名提交: 显示用户AAA的权限: 修改权限(增加article3): 点 ...
- JavaScript(JS)计算某年某月的天数(月末)
方法1 /** * 获取某年月的天数 * @param year 年 * @param month 月(0-11) * @returns {number} 天数 */ var getDaysOfMon ...
- python7
字典-dict 字典也是一种组合数据,没有顺序的组合数据,数据以键值对的方式存在 字典的定义 1.创建空字符串 变量 = {} 或者 变量 = dict() 2 ...
- JavaScript之如何对客户端进行检测
本文主要是针对各种客户端进行检测,使用了用户代理字符串检测技术,具体代码如下: var client=function() { var engine= { // 呈现引擎 ie: 0, gecko: ...
- spring下应用@Resource, @Autowired 和 @Inject注解进行依赖注入的差异
为了探寻 '@Resource', '@Autowired', 和'@Inject'如何解决依赖注入中的问题,我创建了一个"Party"接口,和它的两个实现类"Perso ...
- Python入门-内置函数二
看到标题你也能猜到今天要说大概内容是什么了,没错,昨天没有说完的部分再给大家说说(有一些重合的部分),内置函数的内容比较多,并且工作中经常用到的却不太多,很多都是不太常用的,所以我就着重说一些比较常用 ...
- Python入门-函数进阶
昨天我们简单的了解了函数的定义,调用,以及传参,其实还有一个更重要的传参:动态传参,让我们继续昨天没有说完的,以及今天我要分享的东西. 一.动态传参 之前我们说过了传参,如果我们需要给一个函数传参,而 ...