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 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时 ...
随机推荐
- SpringBoot2.0+ElasticSearch网盘搜索实现
1.ES是如何实现分布式高并发全文检索 2.简单介绍ES分片Shards分片技术 3.为什么ES主分片对应的备分片不在同一台节点存放 4.索引的主分片定义好后为什么不能做修改 5.ES如何实现高可用容 ...
- Dos命令的巧用 - 转载
Dos命令的巧用 豪华绚丽的Windows让人们把DOS抛到遥远的记忆角落,然而,真正有价值的东西不会轻易退出历史的舞台.很多人都已经习惯于 Windows的图形化用户界面,熟不知古老的DOS命令却可 ...
- spring cloud 基本小结
Spring cloud系列十四 分布式链路监控Spring Cloud Sleuth https://blog.csdn.net/hry2015/article/details/78905489 S ...
- NumPy IO文件操作
NumPy - IO ndarray对象可以保存到磁盘文件并从磁盘文件加载. 可用的 IO 功能有: load()和save()函数处理 numPy 二进制文件(带npy扩展名) loadtxt()和 ...
- apue.3e源码下载及编译
下载地址:http://www.apuebook.com/code3e.html 编译方法:http://blog.sina.com.cn/s/blog_94977c890102vdms.html
- DOM冒泡事件
一.注册事件的三种方式 1 on的方式 语法: 事件源.on+事件名称 = 事件处理程序 例如: btn.onclick = function(){} 细节: 只能注册一个事件处理函数 兼容: 所有主 ...
- .net操作Oracle数据库步骤及方法
1.首先安装PL/SQL Developer Oracle客户端软件 2.安装Oracle Instant Client(即时客户端) 安装与配置 配置环境变量ORAClE HOME 地址为insta ...
- Android两个Activity之间的数据交换
1. 不带数据 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceS ...
- Oracle DBLink连接数过多的问题(Ora-02020)
前不久开发人员编译存储时报ORA -02020 错,如下是解决方案步骤. 报错全信息: Error:OR A -04052在查: 找远程对象 NIP.PB_PERADDRESSLIST@DB_NI ...
- C# WinForm开发系列之c# 通过.net自带的chart控件绘制饼图,柱形图和折线图的基础使用和扩展
一.需要实现的目标是: 1.将数据绑定到pie的后台数据中,自动生成饼图. 2.生成的饼图有详细文字的说明. 1.设置chart1的属性Legends中默认的Legend1的Enable为false: ...