Codeforces #123D: 后缀数组+单调栈
You are given a string s. Each pair of numbers l and r that fulfill the condition 1 ≤ l ≤ r ≤ |s|, correspond to a substring of the string s, starting in the position l and ending in the position r (inclusive).
Let's define the function of two strings F(x, y) like this. We'll find a list of such pairs of numbers for which the corresponding substrings of string x are equal to string y. Let's sort this list of pairs according to the pair's first number's increasing. The value of function F(x, y)equals the number of non-empty continuous sequences in the list.
For example: F(babbabbababbab, babb) = 6. The list of pairs is as follows:
(1, 4), (4, 7), (9, 12)
Its continuous sequences are:
- (1, 4)
- (4, 7)
- (9, 12)
- (1, 4), (4, 7)
- (4, 7), (9, 12)
- (1, 4), (4, 7), (9, 12)
Your task is to calculate for the given string s the sum F(s, x) for all x, that x belongs to the set of all substrings of a string s.
The only line contains the given string s, consisting only of small Latin letters (1 ≤ |s| ≤ 105).
Print the single number — the sought sum.
Please do not use the %lld specificator to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specificator.
aaaa
20
abcdef
21
abacabadabacaba
188
In the first sample the function values at x equal to "a", "aa", "aaa" and "aaaa" equal 10, 6, 3 and 1 correspondingly.
In the second sample for any satisfying x the function value is 1.
题意:如果某一种子串s在原串中出现了k次,根据题目定义的函数,它产生的贡献是(k+1)*k/2
这个条件很奇怪,我们尝试转化模型,就会发现这个函数相当于我们将这k个s串排成一排,每个
串和它自己以及后面的串匹配一次,总次数就是题目要求的函数
于是我们可以上后缀数组+高度数组,对于每一个后缀,和后面的每一个后缀的算一个最长公共前缀,然后根据长度统计答案
这个东西可以用单调栈搞一搞,最后每个后缀和自己可以匹配一次,也就是说如果读入的串长度为n,ans+=(n+1)*n/2
代码:
//#include"bits/stdc++.h"
#include"cstdio"
#include"map"
#include"set"
#include"cmath"
#include"queue"
#include"vector"
#include"string"
#include"ctime"
#include"stack"
#include"deque"
#include"cstdlib"
#include"cstring"
#include"iostream"
#include"algorithm" #define db double
#define ll long long
#define vec vector<ll>
#define Mt vector<vec>
#define ci(x) scanf("%d",&x)
#define cd(x) scanf("%lf",&x)
#define cl(x) scanf("%lld",&x)
#define pi(x) printf("%d\n",x)
#define pd(x) printf("%f\n",x)
#define pl(x) printf("%lld\n",x)
//#define rep(i, x, y) for(int i=x;i<y;i++)
#define rep(i, n) for(int i=0;i<n;i++)
using namespace std;
const int N = 1e6 + ;
const int mod = 1e9 + ;
const int MOD = mod - ;
const int inf = 0x3f3f3f3f;
const db PI = acos(-1.0);
const db eps = 1e-;
int sa[N];
int rk[N];
int tmp[N];
int lcp[N];
int n,k;
bool cmp(int i,int j){
if(rk[i] != rk[j]) return rk[i]<rk[j];
else
{
int ri=i+k<=n?rk[i+k]:-;
int rj=j+k<=n?rk[j+k]:-;
return ri<rj;
}
}
void bulid(string s,int *sa)
{
n=(int)s.size();
for(int i=;i<=n;i++){
sa[i]=i;
rk[i]=i<n?s[i]:-;
}
for(k=;k<=n;k*=){
sort(sa,sa+n+,cmp);
tmp[sa[]]=;
for(int i=;i<=n;i++){
tmp[sa[i]]=tmp[sa[i-]]+(cmp(sa[i-],sa[i])?:);
}
for(int i=;i<=n;i++){
rk[i]=tmp[i];
}
}
}
void LCP(string s,int *sa,int *lcp){
n=(int)s.size();
for(int i=;i<=n;i++) rk[sa[i]]=i;
int h=;
lcp[]=;
for(int i=;i<n;i++){
int j=sa[rk[i]-];
for (h ? h-- : ; j + h < n&&i + h < n&&s[j + h] == s[i + h]; h++);
lcp[rk[i]-] = h;
}
}
#define x first
#define y second
#define Pair pair<int,int>
#define mp make_pair stack<Pair> sta;
int main ()
{
string s;
cin>>s;
n=s.length();
bulid(s,sa);
LCP(s,sa,lcp);
ll ans=(ll)n*(ll)(n+)/;
ll cnt=;
for (int i=;i<=n;i++)
{
Pair ins=mp(lcp[i],);//贡献为lcp[i]*num
while (!sta.empty() && sta.top().x>ins.x)
{
cnt-=(ll)sta.top().x*sta.top().y;
ins.y+=sta.top().y;
sta.pop();
}
cnt+=(ll)ins.x*ins.y;
sta.push(ins);
ans+=cnt;
}
cout<<ans<<endl;
return ;
}
Codeforces #123D: 后缀数组+单调栈的更多相关文章
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- BZOJ_3879_SvT_后缀数组+单调栈
BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
- 【BZOJ3879】SvT 后缀数组+单调栈
[BZOJ3879]SvT Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干 ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- BZOJ4199 [Noi2015]品酒大会 【后缀数组 + 单调栈 + ST表】
题目 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品 酒家"和"首席猎手"两个奖项,吸 ...
- poj 3415 Common Substrings 后缀数组+单调栈
题目链接 题意:求解两个字符串长度 大于等于k的所有相同子串对有多少个,子串可以相同,只要位置不同即可:两个字符串的长度不超过1e5; 如 s1 = "xx" 和 s2 = &qu ...
- poj 3415 Common Substrings(后缀数组+单调栈)
http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Sub ...
随机推荐
- 乘风破浪:LeetCode真题_005_Longest Palindromic Substring
乘风破浪:LeetCode真题_005_Longest Palindromic Substring 一.前言 前面我们已经提到过了一些解题方法,比如递推,逻辑推理,递归等等,其实这些都可以用到动态规划 ...
- 四种Timer的区别和用法
1.System.Threading.Timer 线程计时器 1.最底层.轻量级的计时器.基于线程池实现的,工作在辅助线程. 2.它并不是内在线程安全的,并且使用起来比其他计时器更麻烦.此计时器通常不 ...
- 13、Node.js 全局对象
主要用于调试,显示信息,重点看例子在浏览器 JavaScript 中,通常 window 是全局对象, Node.js 中的全局对象是 global ####__filename__filename ...
- 微服务框架SpringCloud(Dalston版)学习 (一):Eureka服务注册与发现
eureka-server eureka服务端,提供服务的注册与发现,类似于zookeeper 新建spring-boot工程,pom依赖: <dependency> <groupI ...
- AI-Info-Micron:用内存解决方案演化神经网络智能
ylbtech-AI-Info-Micron:用内存解决方案演化神经网络智能 1.返回顶部 1. 用内存解决方案演化神经网络智能 我们的大脑每天会进行数千次极其复杂的操作.无论是提醒我们小心被炉子烫到 ...
- MyBatis保存完整日期的解决方法
在用mybatis时,对mysql数据库是datatime字段添加值是,发现添加成功后查看数据库字段值是,只有年月日有值,时分秒则为0来表示的,更改为java.sql.date,time等也不行,如果 ...
- 【luogu P1608 路径统计】 题解
题目链接:https://www.luogu.org/problemnew/show/P1608 补上一发最短路计数! 感谢王强qwqqqq @Lance1ot #include <queue& ...
- linux 下线程错误查找,与线程分析命令
一. 使用top和jstack查找线程错误 我们使用jdk自带的jstack来分析.当linux出现cpu被java程序消耗过高时,以下过程说不定可以帮上你的忙: 1.top查找出哪个进程消耗的cpu ...
- rsync + mysql + gzip + --single-transaction
1.rsync -avz 172.16.2.61:~/vs/program/elasticsearch-5.0.0 --exclude=elasticsearch-5.0.0/data/* ./ 从其 ...
- 分布式消息通信ActiveMQ
消息中间件 消息中间件是指利用高效可靠的消息传递机制进行平台无关的数据交流,并且基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,可以在分布式架构下扩展进程之间的通信. 消息中间件能 ...