BZOJ 2119 股市的预测 (后缀数组+RMQ)
题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的
有点像[NOI2016]优秀的拆分这道题
先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表
进入正题
$ABA$串有一个神奇的性质
令$A$串长度是$x$
如果我们选取了一个位置$i$,再选取一个位置$i+x+m$
用预处理的$st$表,求出经过它们的,最长的相同子串的起始位置$s$和结束位置$e$
合法的$ABA$串似乎在$[s,e]$之间滑动
有了这个性质,我们再外层枚举长度$x$,在序列中找出一些相隔为$x$的关键点,求滑动窗口的左$A$串部分,每次当且仅当覆盖一个关键点时,能覆盖的最长距离总和
总时间$O(n(lnn+logn))$
别像我一样把RMQ打错还调了20min
#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 50500
#define ll long long
#define uint unsigned int
#define rint register int
#define il inline
#define it map<int,int>::iterator
#define inf 0x3f3f3f3f
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} int n,m,len,nn;
int lg[N1];
struct SA{
int a[N1],tr[N1],rk[N1],hs[N1],sa[N1],h[N1],f[N1][];
int check(int i,int j,int k){
if(i+k>len||j+k>len) return ;
return (rk[i]==rk[j]&&rk[i+k]==rk[j+k])?:;
}
void Pre()
{
rint i,cnt=;
for(i=;i<=len;i++) hs[a[i]]++;
for(i=;i<=nn;i++) if(hs[i]) tr[i]=++cnt;
for(i=;i<=nn;i++) hs[i]+=hs[i-];
for(i=;i<=len;i++) rk[i]=tr[a[i]],sa[hs[a[i]]--]=i;
for(int k=;cnt<len;k<<=)
{
for(i=;i<=cnt;i++) hs[i]=;
for(i=;i<=len;i++) hs[rk[i]]++;
for(i=;i<=cnt;i++) hs[i]+=hs[i-];
for(i=len;i>=;i--) if(sa[i]>k) tr[sa[i]-k]=hs[rk[sa[i]-k]]--;
for(i=;i<=k;i++) tr[len-i+]=hs[rk[len-i+]]--;
for(i=;i<=len;i++) sa[tr[i]]=i;
for(i=,cnt=;i<=len;i++) tr[sa[i]]=check(sa[i],sa[i-],k)?cnt:++cnt;
for(i=;i<=len;i++) rk[i]=tr[i];
}
for(i=;i<=len;i++){
if(rk[i]==) continue;
for(int j=max(,h[rk[i-]]-);;j++)
if(a[i+j-]==a[sa[rk[i]-]+j-]) h[rk[i]]=j;
else break;
}
for(i=;i<=len;i++) f[i][]=h[i];
for(int j=;j<=lg[len];j++)
for(i=;i+(<<j)-<=len;i++)
f[i][j]=min(f[i][j-],f[i+(<<(j-))][j-]);
}
int query(int i,int j){
int x=rk[i],y=rk[j];
if(x>y) swap(x,y);x++;int _L=y-x+;
if(_L<) return ;
return min(f[x][lg[_L]],f[y-(<<lg[_L])+][lg[_L]]);
}
}p,s;
int a[N1],A[N1],tmp[N1];
int lower(int l,int r,int *t,int val){
int ans=-inf,id,mid;
while(l<=r){
mid=(l+r)>>;
if(t[mid]<=val&&t[mid]>ans) ans=t[mid],id=mid,l=mid+;
else r=mid-;
}return id;
} int main()
{
scanf("%d%d",&n,&m);
rint i,j;len=n-;
for(lg[]=,i=;i<=n;i++) lg[i]=lg[i>>]+;
A[]=gint();
for(i=;i<=n;i++) A[i]=gint(),a[i-]=tmp[i-]=A[i]-A[i-];
sort(tmp+,tmp+len+);
nn=unique(tmp+,tmp+len+)-(tmp+);
for(i=;i<=len;i++) a[i]=lower(,nn,tmp,a[i]);
for(i=;i<=len;i++) s.a[i]=a[len-i+],p.a[i]=a[i];
p.Pre(),s.Pre();
int lx,rx;ll ans=;
for(j=;j<=len;j++)
{
for(i=;i+j+m<=len;i+=j)
{
lx=min(s.query(len-i+,len-(i+j+m)+),j);
rx=min(p.query(i+,i++j+m),j-);
ans+=max(,lx+rx-j+);
}
}
printf("%lld\n",ans);
return ;
}
/*
2 2 2 3 2 1 2 2 2 3 2 1 2 2 2 3 2
2
2 1 2 2 2 3 2
2 2 2 3 2
2 2 2 3 2 1 2 2 2 3 2
2 2 3 2
2 2 3 2 1 2 2 2 3 2
2 3 2
2 3 2 1 2 2 2 3 2
3 2
3 2 1 2 2 2 3 2 2 3 2 2 2 1 2 3 2 2 2 1 2 3 2 2 2
2
2 1 2 3 2 2 2
2 2
2 2 1 2 3 2 2 2
2 2 2
2 2 2 1 2 3 2 2 2
2 3 2 2 2
2 3 2 2 2 1 2 3 2 2 2
3 2 2 2
3 2 2 2 1 2 3 2 2 2
*/
BZOJ 2119 股市的预测 (后缀数组+RMQ)的更多相关文章
- BZOJ 2119: 股市的预测 [后缀数组 ST表]
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 331 Solved: 153[Submit][Status][Discuss ...
- 【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 2119 股市的预测(后缀数组)
首先要差分+离散化. 然后就是求形如ABA的串有多少,其中B的长度确定为k. 我们用到了设置关键点的思想.我们枚举A的长度L.然后在\(1,1+L,1+L*2,1+L*3...\)设置关键点.然后我们 ...
- 【BZOJ2119】股市的预测 后缀数组+分块
[BZOJ2119]股市的预测 Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰 ...
- ●BZOJ 2119 股市的预测
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2119 题解: 这个题很好的. 首先把序列转化为差分序列,问题转化为找到合法的子序列,使得去除 ...
- bzoj 2119 股市的预测 —— 枚举关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2119 思路就是对于这个形如 ABA 的串,枚举 A 的长度,并按照长度分出几块,找到一些关键 ...
- bzoj 2119 股市的预测——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2119 就是找差分序列上中间差 m 的相等的两段. 考虑枚举这样一段的长度 L .可以把序列分 ...
- BZOJ 2119: 股市的预测 (Hash / 后缀数组 + st表)
转博客大法好 自己画一画看一看,就会体会到这个设置关键点的强大之处了. CODE(sa) O(nlogn)→1436msO(nlogn)\to 1436msO(nlogn)→1436ms #inclu ...
随机推荐
- Project Euler 33 Digit cancelling fractions
题意:49/98是一个有趣的分数,因为可能在化简时错误地认为,等式49/98 = 4/8之所以成立,是因为在分数线上下同时抹除了9的缘故.分子分母是两位数且分子小于分母的这种有趣的分数有4个,将这四个 ...
- LVS的使用
lvs: Linux Virtual Server l4:四层交换:四层路由: 根据请求报文的目标IP和PORT将其转发至后端主机集群中的某一台主机(根据挑选算法): netfilter: PRERO ...
- MarkdownPad 2 安装使用之二三事
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50685187 官网:http://ma ...
- 关于参数net_buffer_length How MySQL Uses Memory
http://dev.mysql.com/doc/refman/5.6/en/memory-use.html The following list indicates some of the ways ...
- Elasticsearch 7.0 发布都有哪些新特性
了解about云知识星球 .pcb{margin-right:0} 问题导读 1.Elasticsearch&Kibana 7.哪些需要修改? 2.Elasticsearch7 有哪些新特性? ...
- yii2.0 表单小部件常用的默认选中
下面自己总结了一下表单小部件中经常使用到的一些默认选中 直接在视图代码里面说明啦 <?php //这个表头就不多说了 use yii\helpers\Html; use yii\widgets\ ...
- nodejs-app.js
设置静态目录 1 2 app.use(express.static(path.join(__dirname, 'public'))); //设置模版渲染的js,css,images的静态文件目录 设置 ...
- bzoj 3236: [Ahoi2013]作业(缺线段树)
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1744 Solved: 702[Submit][Status ...
- Linux 下安装 jdk-7u79-linux-x64.gz,jdk1.7.0_79,jdk1.7步骤:
1.首先下载对应CentOS版本的jdk:这里我下载的是jdk-7u79-linux-x64.tar.gz 2.上传到CentOS下的目录中 3.新建一个APP目录作为存储jdk的目录 4.解压jdk ...
- bzoj1588: [HNOI2002]营业额统计(splay)
1588: [HNOI2002]营业额统计 题目:传送门 题解: 复习splay所以来刷个水... 题目描述不是特别清楚:应该是找第i天以前一个最小的营业额和第i天做差的最小值作为第i天的最小波动值 ...