https://www.lydsy.com/JudgeOnline/problem.php?id=2119

题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0

1、后缀数组求出 差分序列 和 翻转差分序列后的序列 的sa,rk,height

2、枚举len=|A|,对差分序列每len个分一块,记每一块的关键点位块内第一个元素

3、枚举每一个关键点i,令j=i+len+m,求出若i作为A的最后一个元素,向左能延伸最远点x,若i作为A的第一个元素,向右能延伸的最远点y

  那么i取[x,y]内的任意长为len的一块都可以最为A,所以答案累加 y-x+1 - len +1

4、为避免重复,限制向左向右最长延伸长度为len-1,即每个A只能占据一个关键点

5、向左能延伸的最远点就是 分别以i、j结尾的最长公共后缀,即求[1,i]和[1,j]的最长公共后缀,转化成求翻转序列的最长公共前缀

向右能延伸的最远点就是 分别以i、j开始的最长公共前缀,即求[i,n]和[j,n]的最长公共前缀

这可以用后缀数组完成

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; #define N 50001
#define M 15 typedef long long LL; int n,m,tot;
int b[N]; int a1[N],a2[N]; int has[N]; int sa1[][N],rk1[][N],h1[N];
int sa2[][N],rk2[][N],h2[N]; int p1,q1=;
int p2,q2=;
int v[N];
int k; int st1[N][M+],st2[N][M+]; void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
} void mul(int *sa,int *rk,int*SA,int *RK)
{
for(int i=;i<=n;++i) v[rk[sa[i]]]=i;
for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+;i<=n;++i) SA[v[rk[i]]--]=i;
for(int i=;i<=n;++i) RK[SA[i]]=RK[SA[i-]]+(rk[SA[i]]!=rk[SA[i-]] || rk[SA[i]+k]!=rk[SA[i-]+k]);
} void presa(int &p,int &q,int a[N],int sa[][N],int rk[][N])
{
memset(v,,sizeof(v));
for(int i=;i<=n;++i) v[a[i]]++;
for(int i=;i<=tot;++i) v[i]+=v[i-];
for(int i=;i<=n;++i) sa[p][v[a[i]]--]=i;
for(int i=;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(a[sa[p][i]]!=a[sa[p][i-]]);
for(k=;k<n;k<<=,swap(p,q))
mul(sa[p],rk[p],sa[q],rk[q]);
} void get_height(int *a,int *h,int *sa,int *rk)
{
int k=,j;
for(int i=;i<=n;++i)
{
j=sa[rk[i]-];
while(a[i+k]==a[j+k])
k++;
h[rk[i]]=k;
if(k) k--;
}
} void prest(int h[N],int st[N][M+])
{
for(int i=;i<=n;++i) st[i][]=h[i];
for(int i=,k=;i<=M;++i,k<<=)
for(int j=;j+k-<=n;++j)
st[j][i]=min(st[j][i-],st[j+k/][i-]);
} int get(int st[N][M+],int i,int j,int *rk)
{
i=rk[i]; j=rk[j];
if(i>j) swap(i,j);
i++;
int l=1.0*log(j-i+)/log();
return min(st[i][l],st[j-(<<l)+][l]);
} void solve()
{
LL ans=;
int j;
int lcp,lcs,sum;
for(int len=;len<n;++len)
for(int i=;i+len+m<=n;i+=len)
{
j=i+len+m;
lcs=get(st1,i,j,rk1[p1]);
if(lcs>len) lcs=len;
lcp=get(st2,n-j+,n-i+,rk2[p2]);
if(lcp>len) lcp=len;
sum=lcp+lcs-;
if(sum>=len)
{
ans+=sum-len+;
// printf("%d %d %d %d\n",i,j,len,sum-len+1);
}
}
cout<<ans;
} int main()
{
freopen("nt2011_stock.in","r",stdin);
freopen("nt2011_stock.out","w",stdout);
read(n); read(m);
for(int i=;i<=n;++i) read(b[i]);
for(int i=;i<n;++i) a1[i]=b[i+]-b[i],has[i]=a1[i];
n--;
sort(has+,has+n+);
tot=unique(has+,has+n+)-has-;
for(int i=;i<=n;++i) a1[i]=lower_bound(has+,has+tot+,a1[i])-has;
for(int i=;i<=n;++i) a2[n-i+]=a1[i];
presa(p1,q1,a1,sa1,rk1);
get_height(a1,h1,sa1[p1],rk1[p1]);
presa(p2,q2,a2,sa2,rk2);
get_height(a2,h2,sa2[p2],rk2[p2]);
prest(h1,st1);
prest(h2,st2);
solve();
}

bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)的更多相关文章

  1. bzoj千题计划313:bzoj3879: SvT(后缀数组+st表+单调栈)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3879 把所有的后缀取出,按rank排序 求出相邻两个后缀的lcp 每个后缀对答案的贡献就是 与在它 ...

  2. BZOJ 2119: 股市的预测 [后缀数组 ST表]

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 331  Solved: 153[Submit][Status][Discuss ...

  3. BZOJ2119 股市的预测 字符串 SA ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9069171.html 题目传送门 - BZOJ2119 题意 给定一个股票连续$n$个时间点的价位,问有多少段 ...

  4. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  5. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  6. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

  7. 【BZOJ-2119】股市的预测 后缀数组

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 334  Solved: 154[Submit][Status][Discuss ...

  8. 【BZOJ2119】股市的预测 后缀数组+分块

    [BZOJ2119]股市的预测 Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰 ...

  9. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

随机推荐

  1. 【XSY2762】插线板 分块

    题目大意 有\(n\)个插线板,每个插线板会在\(l_i\)时刻初插入到队列中(队列是按插线板的编号排序的),\(r_i\)时刻末移除. 插入一个插线板时会对当前所有接在队列中这个插线的下一个插线板上 ...

  2. new Date()导致日期增加了一天

    问题是:将字符串 "Sun Nov 12 14:00:00 CST 2017"  转成Date类型 有一个简单的方法是直接使用new Date(),但是这个方法对于某些日期的计算, ...

  3. 【cf842C】 Ilya And The Tree(dfs、枚举因子)

    C. Ilya And The Tree 题意 给一棵树求每个点到根的路上允许修改一个为0,gcd的最大值. 题解 g是从根到当前点允许修改的最大gcd,gs为不修改的最大gcd.枚举当前点的因子,更 ...

  4. Hdoj 1050.Moving Tables 题解

    Problem Description The famous ACM (Advanced Computer Maker) Company has rented a floor of a buildin ...

  5. Hdoj 1007 Quoit Design 题解

    Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...

  6. [luogu5004]专心OI - 跳房子【矩阵加速+动态规划】

    传送门:https://www.luogu.org/problemnew/show/P5004 分析 动态规划转移方程是这样的\(f[i]=\sum^{i-m-1}_{j=0}f[j]\). 那么很明 ...

  7. A.01.02—模块的输入—高端输入

    高端输入即一个高电平信号输入到模块,模块采样时最典型的是采用下拉电阻采样,当然,还有限流电阻和分压电阻,具体可以参见实际电路. 高端输入在汽车上用得不多,这种类型的输入既可以是开关提供的也可以是模块提 ...

  8. 单片机pwm控制基本原理详解

    前言 PWM是Pulse Width Modulation的缩写,它的中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信 ...

  9. Hadoop安装错误总结

    Master的NodeManager/DateNode未启动 日志中未出现任何错误 正常现象,如需在Master中启动可在slave文件中 slaves localhost slave01 slave ...

  10. Python经典算法片段

    将一个正整数分解质因数 #!/bin/env python2 # -*- coding: UTF-8 -*- def reduceNum(n): print '{} = '.format(n), if ...