BZOJ2119 股市的预测 字符串 SA ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/9069171.html
题目传送门 - BZOJ2119
题意
给定一个股票连续$n$个时间点的价位,问有多少段股票走势在间隔$m$单位时间之后重现?
$n\leq 5\times 10^4,m\leq 10$
题解
和 http://www.cnblogs.com/zhouzhendong/p/9025092.html 此题十分类似。
这里稍微讲讲本题的不同之处。
首先相邻值求差,转换成字符串匹配。
然后,由于要间隔$m$个字符,所以我们在找关键点的对应点的时候要稍微改一改。
对于得到的$lcs$和$lcp$,在计算的时候有一点小小的注意点。
详见代码。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
int n,m,a[N],tot=0;
map <int,int> mp;
int SA[N],rank[N],tmp[N],height[N],tax[N];
int ST[N][20];
void Sort(int n,int m){
for (int i=0;i<=m;i++)
tax[i]=0;
for (int i=1;i<=n;i++)
tax[rank[i]]++;
for (int i=1;i<=m;i++)
tax[i]+=tax[i-1];
for (int i=n;i>=1;i--)
SA[tax[rank[tmp[i]]]--]=tmp[i];
}
bool cmp(int rk[],int x,int y,int w){
return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
}
void Suffix_Array(int s[],int n){
memset(SA,0,sizeof SA);
memset(tmp,0,sizeof tmp);
memset(rank,0,sizeof rank);
memset(height,0,sizeof height);
for (int i=1;i<=n;i++)
rank[i]=s[i],tmp[i]=i;
int m=tot+1;
Sort(n,m);
for (int w=1,p=0;p<n;w<<=1,m=p){
p=0;
for (int i=n-w+1;i<=n;i++)
tmp[++p]=i;
for (int i=1;i<=n;i++)
if (SA[i]>w)
tmp[++p]=SA[i]-w;
Sort(n,m);
swap(rank,tmp);
rank[SA[1]]=p=1;
for (int i=2;i<=n;i++)
rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
}
for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
height[1]=0;
}
void Get_ST(int n){
memset(ST,0,sizeof ST);
for (int i=1;i<=n;i++){
ST[i][0]=height[i];
for (int j=1;j<20;j++){
ST[i][j]=ST[i][j-1];
if (i-(1<<(j-1))>0)
ST[i][j]=min(ST[i][j],ST[i-(1<<(j-1))][j-1]);
}
}
}
int Query(int L,int R){
int val=floor(log(R-L+1)/log(2));
return min(ST[L+(1<<val)-1][val],ST[R][val]);
}
int LCP(int x,int y){
x=rank[x],y=rank[y];
return Query(min(x,y)+1,max(x,y));
}
int LCS(int x,int y){
return LCP(n*2+2-x,n*2+2-y);
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
n--;
mp.clear();
for (int i=1;i<=n;i++){
a[i]=a[i+1]-a[i];
if (mp[a[i]]==0)
mp[a[i]]=++tot;
a[n*2+2-i]=a[i]=mp[a[i]];
}
a[n+1]=tot+1;
Suffix_Array(a,n*2+1);
Get_ST(n*2+1);
LL ans=0;
for (int L=1;L<=n;L++)
for (int i=1;i+L+m<=n;i+=L){
int x=i,y=i+L+m;
int lcp=min(LCP(x,y),L),lcs=min(LCS(x,y),L);
int len=lcp+lcs-(lcp>0&&lcs>0);
ans+=max(len-L+1,0);
}
printf("%lld\n",ans);
return 0;
}
BZOJ2119 股市的预测 字符串 SA ST表的更多相关文章
- BZOJ2534 Uva10829L-gap字符串 字符串 SA ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/9240665.html 题目传送门 - BZOJ2534 题意 有一种形如 $uvu$ 形式的字符串,其中 $u ...
- BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...
- BZOJ3172 [Tjoi2013]单词 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...
- UOJ#219/BZOJ4650 [NOI2016]优秀的拆分 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9025092.html 题目传送门 - UOJ#219 (推荐,题面清晰) 题目传送门 - BZOJ4650 题意 ...
- BZOJ 2119: 股市的预测 [后缀数组 ST表]
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 331 Solved: 153[Submit][Status][Discuss ...
- BZOJ3230 相似子串 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9033092.html 题目传送门 - BZOJ3230 题意 给定字符串$s$.长度为$n$. 现在有$Q$组询 ...
- Codeforces Round #422 (Div. 2)E. Liar sa+st表+dp
题意:给你两个串s,p,问你把s分开顺序不变,能不能用最多k段合成p. 题解:dp[i][j]表示s到了前i项,用了j段的最多能合成p的前缀是哪里,那么转移就是两种,\(dp[i+1][j]=dp[i ...
- [NOI2016]优秀的拆分&&BZOJ2119股市的预测
[NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...
- bzoj 3230: 相似子串【SA+st表+二分】
总是犯低级错误,st表都能写错-- 正反分别做一遍SA,预处理st表方便查询lcp,然后处理a[i]表示前i个后缀一共有多少个本质不同的子串,这里的子串是按字典序的,所以询问的时候直接在a上二分排名就 ...
随机推荐
- mysql:批量插入不同的UUID
INSERT INTO t_base_role_resource_ref (refID, roleID, resID, orgID, belongTo) SELECT uuid() AS refID, ...
- python-GIL、死锁递归锁及线程补充
一.GIL介绍 GIL全称 Global Interpreter Lock ,中文解释为全局解释器锁.它并不是Python的特性,而是在实现python的主流Cpython解释器时所引入的一个概念,G ...
- python之__new__()
__new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...
- 【进阶3-4期】深度解析bind原理、使用场景及模拟实现(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://github.com/yygmind/blog/issues/23 bind() bind() 方法会创建一个新函数,当这个新函 ...
- (转)scikit-learn主要模块和基本使用方法
从网上看到一篇总结的很不错的sklearn使用文档,备份勿忘. 引言 对于一些开始搞机器学习算法有害怕下手的小朋友,该如何快速入门,这让人挺挣扎的.在从事数据科学的人中,最常用的工具就是R和Pytho ...
- socket通讯---TcpClient
IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipa = ipe.AddressList[0]; System.Ne ...
- Confluence 6 数据库问题解除
有关数据库相关的问题,请参考 Database Troubleshooting 中的内容. 希望获得更多的帮助,请参考 Troubleshooting Problems and Requesting ...
- Swift中使用oc代码桥接设置
1 将oc的代码拖入项目中 2 新建一个头文件 在头文件中导入你想用的oc头文件 import "****.h" 3 在设置build Setting 中搜索bird 找到 Ob ...
- java 命令行运行时报错:找不到或无法加载主类
源码如下: 路径目录(...\src\object) //: ch1.10/Command.java /**@author feilong * @version 1.0 */ package obje ...
- Wireless Penetration Testing(7-11 chapter)
1.AP-less WPA-Personal cracking 创建一个honeypoint 等待链接,特点在于不需要攻击致使链接的客户端掉线,直接获取了流量的握手包. 2.Man-in-the-M ...