bzoj 2119 股市的预测 —— 枚举关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2119
思路就是对于这个形如 ABA 的串,枚举 A 的长度,并按照长度分出几块,找到一些关键点就是块的开头;
那么每一种 ABA 的串,A 的部分一定覆盖了一个关键点;
所以找关键点周围的匹配长度算答案,具体就是找和对应位置的 lcp + lcs,那么 ABA 可以在对应匹配的地方滑动,就能找到所有 ABA 了;
因为是差分数组所以 n-1,而且注意连接正反串的字符要比串内字符小,不是 '0'-1 而是 0 ...
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int Min(int x,int y){return x<y?x:y;}
int const xn=1e5+;
int n,mx,d,m,s[xn],t[xn],tt[xn],tax[xn],sa[xn],rk[xn],tp[xn];
int op[xn],ht[xn][],bin[],bit[xn];
void rsort()
{
for(int i=;i<=m;i++)tax[i]=;
for(int i=;i<=mx;i++)tax[rk[tp[i]]]++;
for(int i=;i<=m;i++)tax[i]+=tax[i-];
for(int i=mx;i;i--)sa[tax[rk[tp[i]]]--]=tp[i];
}
void work()
{
for(int i=;i<=mx;i++)rk[i]=s[i],tp[i]=i;
m=n; rsort();
for(int k=;k<=mx;k<<=)
{
int num=;
for(int i=mx-k+;i<=mx;i++)tp[++num]=i;
for(int i=;i<=mx;i++)
if(sa[i]>k)tp[++num]=sa[i]-k;
rsort(); swap(rk,tp);
rk[sa[]]=; num=;
for(int i=;i<=mx;i++)
rk[sa[i]]=(tp[sa[i]]==tp[sa[i-]]&&tp[sa[i]+k]==tp[sa[i-]+k])?num:++num;
if(num==mx)break;
m=num;
}
}
void geth()
{
int k=;
for(int i=;i<=mx;i++)
{
if(rk[i]==)continue;
if(k)k--; int j=sa[rk[i]-];
while(s[i+k]==s[j+k]&&i+k<=mx&&j+k<=mx)k++;
ht[rk[i]][]=k;
}
bin[]=; for(int i=;i<;i++)bin[i]=(bin[i-]<<);
bit[]=; for(int i=;i<=mx;i++)bit[i]=bit[i>>]+;
for(int i=;i<;i++)
for(int j=;j+bin[i]-<=mx;j++)
ht[j][i]=Min(ht[j][i-],ht[j+bin[i-]][i-]);
}
int getlcp(int x,int y)
{
if(x==y)return mx-x+;
x=rk[x]; y=rk[y];
if(x>y)swap(x,y); x++;
int r=bit[y-x+];
return Min(ht[x][r],ht[y-bin[r]+][r]);
}
int main()
{
n=rd(); d=rd();
for(int i=;i<=n;i++)t[i]=rd();
for(int i=n;i>;i--)t[i]=t[i]-t[i-],tt[i]=t[i];
sort(t+,t+n+); int tot=unique(t+,t+n+)-t-;
for(int i=;i<=n;i++)tt[i]=lower_bound(t+,t+tot+,tt[i])-t;
n--; mx=*n+;
for(int i=;i<=n;i++)s[i]=tt[i+];
s[n+]=;//
for(int i=n+,k=n;k;i++,k--)s[i]=s[k],op[k]=i;
work(); geth(); int ans=;
for(int k=;k<=n;k++)
for(int i=;i+k+d<=n;i+=k)
{
int j=i+k+d;
int l1=getlcp(i,j),l2=getlcp(op[i],op[j]);
l1=Min(l1,k); l2=Min(l2,k);
if(l1&&l2&&l1+l2->=k)ans+=l1+l2--k+;
else if(l1&&l1>=k)ans+=l1-k+;
else if(l2&&l2>=k)ans+=l2-k+;
}
printf("%d\n",ans);
return ;
}
bzoj 2119 股市的预测 —— 枚举关键点+后缀数组的更多相关文章
- bzoj 2119 股市的预测——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2119 就是找差分序列上中间差 m 的相等的两段. 考虑枚举这样一段的长度 L .可以把序列分 ...
- BZOJ 2119: 股市的预测 [后缀数组 ST表]
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 331 Solved: 153[Submit][Status][Discuss ...
- BZOJ 2119: 股市的预测 SA
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 434 Solved: 200[Submit][Status][Discuss ...
- BZOJ 2119 股市的预测(后缀数组)
首先要差分+离散化. 然后就是求形如ABA的串有多少,其中B的长度确定为k. 我们用到了设置关键点的思想.我们枚举A的长度L.然后在\(1,1+L,1+L*2,1+L*3...\)设置关键点.然后我们 ...
- ●BZOJ 2119 股市的预测
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2119 题解: 这个题很好的. 首先把序列转化为差分序列,问题转化为找到合法的子序列,使得去除 ...
- bzoj 4650 & 洛谷 P1117 优秀的拆分 —— 枚举关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4650 https://www.luogu.org/problemnew/show/P1117 ...
- BZOJ 2119 股市的预测 (后缀数组+RMQ)
题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的 有点像[NOI2016]优秀的拆分这道题 先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表 进入正题 $ABA$串 ...
- BZOJ 2119: 股市的预测 (Hash / 后缀数组 + st表)
转博客大法好 自己画一画看一看,就会体会到这个设置关键点的强大之处了. CODE(sa) O(nlogn)→1436msO(nlogn)\to 1436msO(nlogn)→1436ms #inclu ...
- bzoj 2119: 股市的预测
Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时 ...
随机推荐
- iOS 开发 申请定位
在iOS8以后,苹果已经强制开发者在请求定位服务时获得用户的授权,此外iOS状态栏中还有指示图标,提示用户当前应用是否正在使用定位服务.另外在iOS8以后,苹果进一步改善了定位服务,让开发者请求定位服 ...
- java 客户端发起http请求2
客户端请求方式一,如果数据类型为 x-www-form-urlencoded 用到的json jar包为 gradle ('com.alibaba:fastjson:1.2.38',) 那么对应的代码 ...
- cookie 与 session 的区别详解
[转]cookie 与session 的区别详解 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择,都纪录下来.当 ...
- Mysql导出数据结构 or 数据
如果我们单单只想导出mysql数据表结构,通过navcat工具还不行,这时我们可以用mysqldump工具 在mysql server的安装目录:C:\Program Files\MySQL\MySQ ...
- Git和GitHub相关
组员从GitHub上下载项目并上传项目的步骤如下 .组员接收到组长发的项目地址,组员需要从GitHub上把项目克隆下来,首先组员 需要在本地的一个文件夹里打开git,然后运行如下代码:git clon ...
- 怎样发布一个工程到自己的GitHub
本人小白一枚: 第一次通过命令行的形式将自己的工程发布到自己的GitHub上去,还是请教了大神之后才完成的.通过总结经验,小白也掌握了一些关于往代码托管平台上发布工程的方式,其实只要用心学,里面的东西 ...
- mysql升级的一些踩坑点
升级的方法一般有两类: 1.利用mysqldump来直接导出sql文件,导入到新库中,这种方法最省事也最保险 缺点:大库的mysqldump费时费力. 2.直接替换掉 mysql 的安装目录和 my. ...
- Load事件
Load事件 在 窗体完全呈现之后 被 触发 如下伪代码: void ShowWindows { .....//显示父容器 .....//显示子容器 .....//显示控件 //至此,窗体完全呈现 ...
- (CSharp)克隆控件事件
// https://stackoverflow.com/questions/6055038/how-to-clone-control-event-handlers-at-run-time // &q ...
- WPF控件开源资源
(转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...