BZOJ2119: 股市的预测(后缀数组)
Description

Input
Output
输出一个整数,表示满足条件的时间段的个数
Sample Input
1 2 3 4 8 9 1 2 3 4 8 9
Sample Output
解题思路:
还是很佩服后缀数组的思维。
这是求一个具有ABA结构的字符串个数。
发现一个性质,如果左右A足够长,
就可以将中间部分左右移动得到新答案。
枚举A的长度L,按L分块,边缘设为关键点。
易知关键点只能被一个串覆盖一次。
只需正反构建后缀数组求Lcp即可。
时间复杂度n(lnn+logn)
代码:
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=;
struct Sa{
int sa[N];
int tmr[N];
int rnk[N];
int has[N];
int str[N];
int hgt[N];
int Rmq[][N];
int lg[N];
int cnt;
int n;
bool Same(int a,int b,int l)
{
if(a+l>n||b+l>n)
return false;
return (rnk[a]==rnk[b])&&(rnk[a+l]==rnk[b+l]);
}
void Insert(int *a,int len)
{
for(int i=;i<=len;i++)
str[i]=a[i];
n=len;
return ;
}
void Reverse(int *a,int len)
{
int j=;
for(int i=len;i;i--)
str[++j]=a[i];
n=len;
return ;
}
void Build(void)
{
for(int i=;i<=n;i++)
lg[i]=lg[i/]+;
for(int i=;i<=n;i++)
has[str[i]]++;
for(int i=;i<=n;i++)
if(has[i])
tmr[i]=++cnt;
for(int i=;i<=n;i++)
has[i]+=has[i-];
for(int i=;i<=n;i++)
{
sa[has[str[i]]--]=i;
rnk[i]=tmr[str[i]];
}
for(int k=;cnt!=n;k<<=)
{
cnt=;
for(int i=;i<=n;i++)
has[i]=;
for(int i=;i<=n;i++)
has[rnk[i]]++;
for(int i=;i<=n;i++)
has[i]+=has[i-];
for(int i=n;i;i--)
if(sa[i]>k)
tmr[sa[i]-k]=has[rnk[sa[i]-k]]--;
for(int i=;i<=k;i++)
tmr[n-i+]=has[rnk[n-i+]]--;
for(int i=;i<=n;i++)
sa[tmr[i]]=i;
for(int i=;i<=n;i++)
if(Same(sa[i],sa[i-],k))
tmr[sa[i]]=cnt;
else
tmr[sa[i]]=++cnt;
for(int i=;i<=n;i++)
rnk[i]=tmr[i];
}
for(int i=;i<=n;i++)
{
if(rnk[i]==)
continue;
int j=std::max(,hgt[rnk[i-]]-);
while(str[i+j-]==str[sa[rnk[i]-]+j-])
hgt[rnk[i]]=j++;
}
for(int i=;i<=n;i++)
Rmq[][i]=hgt[i];
for(int i=;i<=;i++)
for(int j=;j+(<<i)-<=n;j++)
Rmq[i][j]=std::min(Rmq[i-][j],Rmq[i-][j+(<<(i-))]);
return ;
}
int Lcp(int i,int j)
{
i=rnk[i],j=rnk[j];
if(j<i)
i^=j^=i^=j;
i++;
int l=lg[j-i+];
return std::min(Rmq[l][i],Rmq[l][j-(<<l)+]);
}
}S1,S2;
int tmp[N];
int sln[N];
int n,B;
std::map<int,int>M;
int main()
{
//freopen("a.in","r",stdin);
scanf("%d%d",&n,&B);
int cnt=;
for(int i=;i<=n;i++)
scanf("%d",&sln[i]);
for(int i=n;i>=;i--)
sln[i]-=sln[i-];
for(int i=;i<=n;i++)
{
if(M.find(sln[i])==M.end())
M[sln[i]]=++cnt;
tmp[i-]=M[sln[i]];
}
S1.Insert(tmp,n-);
S2.Reverse(tmp,n-);
S1.Build();
S2.Build();
int ans=;
for(int L=;L<=((n-)-B)/;L++)
{
for(int i=;i<=n-;i+=L)
{
int j=i+B+L;
if(j>n-)
continue;
int r=std::min(L,S1.Lcp(i,j));
int l=std::min(L,S2.Lcp(n-i,n-j));
int t=l+r-;
if(t>=L)
ans+=t-L+;
}
}
printf("%d\n",ans);
return ;
}
BZOJ2119: 股市的预测(后缀数组)的更多相关文章
- 【BZOJ2119】股市的预测 后缀数组+分块
[BZOJ2119]股市的预测 Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰 ...
- 【BZOJ-2119】股市的预测 后缀数组
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 334 Solved: 154[Submit][Status][Discuss ...
- BZOJ 2119: 股市的预测 [后缀数组 ST表]
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 331 Solved: 153[Submit][Status][Discuss ...
- BZOJ 2119 股市的预测 (后缀数组+RMQ)
题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的 有点像[NOI2016]优秀的拆分这道题 先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表 进入正题 $ABA$串 ...
- bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)
https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...
- [NOI2016]优秀的拆分&&BZOJ2119股市的预测
[NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...
- BZOJ2119 股市的预测 字符串 SA ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/9069171.html 题目传送门 - BZOJ2119 题意 给定一个股票连续$n$个时间点的价位,问有多少段 ...
- bzoj2119 股市的预测
传送门 感觉智商莫名其妙的就变低了……写这题的时候死活想不出来…… 做法其实不难…… 题目要求形如ABA的串的个数,我们可以枚举A的长度,利用标记关键点的方法统计答案.设枚举到的答案为k,每k个点标记 ...
- bzoj 4650(洛谷 1117) [Noi2016]优秀的拆分——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4650 https://www.luogu.org/problemnew/show/P1117 ...
随机推荐
- To new is C++; To malloc is C; To mix them is sin (混淆C++中的new和C中的malloc是一种犯罪)
Introduction One of the most common questions that get asked during interviews for C++ programmers i ...
- 数据格式转换 (三)Office文档转HTML
HTML Filter 是由北京红樱枫软件有限公司根据HTML Ver 4.01/CSS式样,研制和开发的MS Office系列文档到HTML转换的通用程序库.便于用户实现对多种文档的统一管 ...
- Java之——删除ArrayList中的反复元素的2种方法
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47414935 ArrayList是Java中最经常使用的集合类型之中的一个.它同意 ...
- HTML <button> 标签
HTML <button> 标签 目标 实现点击button跳转到一个新的界面 参考文档 实例 以下代码标记一个按钮: <button type="button" ...
- django 笔记3
FBV function base view url.py index -> 函数名 view.py def 函数(requset): ... CBV class base view /inde ...
- SQL 小技能
1. SET STATISTICS TIMEON 附带原文 2.关于索引,是自己可以用Tsql语句建,也可以在设计表的时候选中某一个字段建立索引 一般而言,主键属于聚合索引(字典:A-Z);反 ...
- 记录一下 mysql 的查询中like字段的用法
SELECT * from t_yymp_auth_role where role_name not like '%测试%' and role_name not like '%部门%' and rol ...
- SQL try catch处理
ALTER PROC usp_AccountTransaction @AccountNum INT, @Amount DECIMAL AS BEGIN BEGIN TRY --Start the Tr ...
- Debian9.5 配置x11vnc远程桌面
x11vnc是一个VNC服务器,它允许用户远程查看并用任何VNC查看器与真实的X显示器(即与物理监视器,键盘和鼠标相对应的显示器)进行交互.虽然它的原作者Karl Runge不再开发,但LibVNC和 ...
- Flex之柱状图实例
Flex之柱状图实例 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns ...