BZOJ 2119: 股市的预测 [后缀数组 ST表]
2119: 股市的预测
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 331 Solved: 153
[Submit][Status][Discuss]
Description
墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势。股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况。经过长时间的观测,墨墨发现很多股票都有如下的规律:之前的走势很可能在短时间内重现!如图可以看到这只股票A部分的股价和C部分的股价的走势如出一辙。通过这个观测,墨墨认为他可能找到了一个预测股票未来走势的方法。进一步的研究可是难住了墨墨,他本想试图统计B部分的长度与发生这种情况的概率关系,不过由于数据量过于庞大,依赖人脑的力量难以完成,于是墨墨找到了善于编程的你,请你帮他找一找给定重现的间隔(B部分的长度),有多少个时间段满足首尾部分的走势完全相同呢?当然,首尾部分的长度不能为零。
Input
输入的第一行包含两个整数N、M,分别表示需要统计的总时间以及重现的间隔(B部分的长度)。接下来N行,每行一个整数,代表每一个时间点的股价。
Output
输出一个整数,表示满足条件的时间段的个数
Sample Input
1 2 3 4 8 9 1 2 3 4 8 9
Sample Output
【样例说明】
6个时间段分别是:3-9、2-10、2-8、1-9、3-11、4-12。
HINT
对于100%的数据,4≤N≤50000 1≤M≤10 M≤N 所有出现的整数均不超过32位含符号整数。
走势相同,再次用到差分
还要离散化
然后就是求有多少子串样子是ABA
然后,和上题相似的思路,枚举走势相同的长度L,每L设一个关键点
发现对于一个ABA,第一个A一定覆盖且只覆盖一个关键点,
枚举关键点i,i和i+B+L往左往右匹配长度l和r(同样,我的r包括关键点),如果l+r>=L那么这个地方就有l+r-L+1个满足的子串
(i)--L--B--(i+B+L)--L--
为了做到不重复,左右延伸最大长度为L-1
为什么这样就不重复了?我这个煞笔竟然想了好长时间,因为上面的蓝色字体,每个关键点延伸出来的,第一个L一定覆盖了这个关键点,从其他关键点开始的都不覆盖,所以不重复不遗漏
注意:
1.计数排序最后是倒序
2.因为我的r包括关键点,所以最大是L不是L-1
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=5e4+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int B,s[N],mp[N],tot;
int n,m,c[N],t1[N],t2[N];
int Bin(int v){
int l=,r=tot;
while(l<=r){
int mid=(l+r)>>;
if(mp[mid]==v) return mid;
else if(v<mp[mid]) r=mid-;
else l=mid+;
}
return ;
}
inline bool cmp(int *r,int a,int b,int j){
return a+j<=n&&b+j<=n&&r[a]==r[b]&&r[a+j]==r[b+j];
}
int Log[N],Pow[],mn[N][]; void iniST(){
Pow[]=;for(int i=;i<;i++)Pow[i]=Pow[i-]<<;
Log[]=-;for(int i=;i<=n;i++)Log[i]=Log[i/]+;
}
void getST(int mn[N][],int a[]){
for(int i=;i<=n;i++) mn[i][]=a[i];
for(int j=;j<=Log[n];j++)
for(int i=;i+Pow[j]-<=n;i++)
mn[i][j]=min(mn[i][j-],mn[i+Pow[j-]][j-]);
} struct SA{
int sa[N],rnk[N],height[N],mn[N][]; void getHeight(){
int k=;
for(int i=;i<=n;i++) rnk[sa[i]]=i;
for(int i=;i<=n;i++){
if(k) k--;
if(rnk[i]==) continue;
int j=sa[rnk[i]-];
while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
height[rnk[i]]=k;
}
}
void getSA(){
int *r=t1,*k=t2;
for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[r[i]=s[i]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[i]]--]=i; for(int j=;j<=n;j<<=){
int p=;
for(int i=n-j+;i<=n;i++) k[++p]=i;
for(int i=;i<=n;i++) if(sa[i]>j) k[++p]=sa[i]-j; for(int i=;i<=m;i++) c[i]=;
for(int i=;i<=n;i++) c[r[k[i]]]++;
for(int i=;i<=m;i++) c[i]+=c[i-];
for(int i=n;i>=;i--) sa[c[r[k[i]]]--]=k[i]; swap(r,k);p=;r[sa[]]=++p;
for(int i=;i<=n;i++) r[sa[i]]=cmp(k,sa[i],sa[i-],j)?p:++p;
if(p>=n) break;m=p;
}
} int lcp(int x,int y){//printf("lcp %d %d\n",x,y);
x=rnk[x];y=rnk[y];
if(x>y) swap(x,y);x++;//printf("rnk %d %d\n",x,y);
int t=Log[y-x+];//printf("t %d %d %d\n",t,mn[x][t],mn[y-Pow[t]+1][t]);
return min(mn[x][t],mn[y-Pow[t]+][t]);
} void ini(){
getSA();getHeight();getST(mn,height);
}
void test(){
puts("test");
for(int i=;i<=n;i++) printf("%d ",s[i]);puts("");
for(int i=;i<=n;i++) printf("%d ",rnk[i]);puts("");
for(int i=;i<=n;i++) printf("%d ",sa[i]);puts("");
for(int i=;i<=n;i++) printf("%d ",height[i]);puts("");
puts("");
}
}a,b; int ans;
void solve(int L){//printf("sol %d\n",L);
for(int i=;i+B+L<=n;i+=L)
if(s[i]==s[i+B+L]){//puts("begin");
int r=a.lcp(i,i+B+L),l=b.lcp(n-i+,n-i-B-L+);
l=min(l,L-);r=min(r,L); //printf("ss %d %d %d %d\n",i,i+B+L,l,r);
if(l+r>=L) ans+=l+r+-L;//,printf("hi %d %d\n",i,i+B+L);
//puts("end");
}
} int main(){
//freopen("in.txt","r",stdin);
n=read();B=read();
for(int i=;i<=n;i++){
s[i]=read();
if(i!=) mp[++tot]=s[i-]=s[i]-s[i-];
}
n--;
sort(mp+,mp++n);
tot=;mp[++tot]=mp[];
for(int i=;i<=n;i++) if(mp[i]!=mp[i-]) mp[++tot]=mp[i];
for(int i=;i<=n;i++) s[i]=Bin(s[i]);
m=n; iniST();
a.ini();//a.test();
reverse(s+,s++n);
b.ini();//b.test();
reverse(s+,s++n);
for(int L=;L+L+B<=n;L++) solve(L);
printf("%d",ans);
}
BZOJ 2119: 股市的预测 [后缀数组 ST表]的更多相关文章
- BZOJ 2119 股市的预测 (后缀数组+RMQ)
题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的 有点像[NOI2016]优秀的拆分这道题 先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表 进入正题 $ABA$串 ...
- BZOJ 4556 [Tjoi2016&Heoi2016]字符串 ——后缀数组 ST表 主席树 二分答案
Solution 1: 后缀数组暴力大法好 #include <map> #include <cmath> #include <queue> #include &l ...
- SPOJ 687 Repeats(后缀数组+ST表)
[题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i ...
- POJ 3693 Maximum repetition substring(后缀数组+ST表)
[题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...
- BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...
- UVA10829 L-Gap Substrings(后缀数组+ST表)
后缀数组+ST表. 代填的坑. \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace ...
- 【BZOJ-2119】股市的预测 后缀数组
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 334 Solved: 154[Submit][Status][Discuss ...
- BZOJ 2119: 股市的预测 SA
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 434 Solved: 200[Submit][Status][Discuss ...
- bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)
https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...
随机推荐
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 【CSS进阶】伪元素的妙用--单标签之美
最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...
- Java 征途:行者的地图
前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大约在 2003 年我开始知道 Java 的(当时还在用 Delph ...
- java基础_集合List与Set接口
List接口继承了Collection的方法 当然也有自己特有的方法向指定位置添加元素 add(索引,添加的元素); 移除指定索引的元素 remove(索引) 修改指定索引的元素 set ...
- Webstorm+Webpack+echarts构建个性化定制的数据可视化图表&&两个echarts详细教程(柱状图,南丁格尔图)
Webstorm+Webpack+echarts ECharts 特性介绍 ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(I ...
- C# 多种方式发送邮件(附帮助类)
因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...
- System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
在NHibernate数据库查询中出现了这个错误,由于是数据库是mysql的,当定义的字段为char(36)的时候就会出现这个错误. [解决方法] 将char(36) 改成varchar(40)就行了 ...
- 如何利用ansible callback插件对执行结果进行解析
最近在写一个批量巡检工具,利用ansible将脚本推到各个机器上执行,然后将执行的结果以json格式返回来. 如下所示: # ansible node2 -m script -a /root/pyth ...
- 在开启DRS的集群中修复VMware虚拟主机启动问题
通过iSCSI方式连接到ESXi主机上的外挂存储意外失联了一段时间,导致部分虚拟主机在集群中呈现出孤立的状态,单独登陆到每台ESXi上可以看到这些虚拟主机都变成了unknow状态.因为有过上一次(VM ...
- 使用po模式读取豆瓣读书最受关注的书籍,取出标题、评分、评论、题材 按评分从小到大排序并输出到txt文件中
#coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...