题意就是差分后求形如ABA的串的个数,B的长度为M

这是2011国家集训队互测的试题,是道好题,我直接给出出题人的题解吧:

对于这种在线性序列上的组合计数问题,我们很容易想到一个工具:分治!分治算法在形如快速排序等地方能顺利优化算法,我们尝试将其运用至本题中。

不妨设过程F(Left,Right)可以统计在区间[Left,Right]中满足条件的子序列的个数。

设Mid为区间[Left,Right]的中点由于分治执行,我们不需要统计那些属于[Left,Mid],[Mid+1,Right]中的子序列,剩下的我们分两种情况讨论。

1、 点Mid∈Q。这种情况由于|Q|非常小,我们可以直接枚举Q的位置,然后我们可以穷举A部分长度,然后后缀数组+RMQ解决这个问题

此时算法多了一个系数M,不过整体仍然可以在O(NMLogN)的复杂度内完成。

2、 点Mid∉Q,这种情况就比较麻烦了,可以表示成如下示意图:

由于Mid的存在,P2被分割成了3份,由于P1=P2,我们把P1也分割成3份,经过仔细观察,我们发现只需要枚举红线的位置即可解决此部分的统计问题。黄色部分的最大匹配值可以通过将整个Mid左面的部分倒置后求LCP可得。而Mid以及绿色部分的匹配值可以直接通过后缀数组+RMQ求的。知道了绿色与黄色部分的最大值后,那么Q的位置个数也可以相应得出,问题得到解决,此部分复杂度为O(NLogN)。

方法三总复杂度为O(NMLogN),为一个非常优秀的算法。

 const eps=1e-8;
var s,h,sa,rank:array[..,..] of longint;
sum,a,b,x,y:array[..] of longint;
f:array[..,..,..] of longint;
d:array[..] of longint;
t,mx,ans,i,n,m:longint; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure suffix(k:longint);
var i,j,m,p:longint;
begin
fillchar(sum,sizeof(sum),);
for i:= to n do
inc(sum[s[i,k]]);
for i:= to mx do
inc(sum[i],sum[i-]);
for i:=n downto do
begin
sa[sum[s[i,k]],k]:=i;
dec(sum[s[i,k]]);
end;
p:=;
rank[sa[,k],k]:=;
for i:= to n do
begin
if s[sa[i,k],k]<>s[sa[i-,k],k] then inc(p);
rank[sa[i,k],k]:=p;
end;
m:=p;
j:=;
while m<n do
begin
for i:= to n do
begin
y[i]:=rank[i,k];
sum[i]:=;
end;
p:=;
for i:=n-j+ to n do
begin
inc(p);
x[p]:=i;
end;
for i:= to n do
if sa[i,k]>j then
begin
inc(p);
x[p]:=sa[i,k]-j;
end; for i:= to n do
begin
a[i]:=y[x[i]];
inc(sum[a[i]]);
end;
for i:= to m do
inc(sum[i],sum[i-]);
for i:=n downto do
begin
sa[sum[a[i]],k]:=x[i];
dec(sum[a[i]]);
end;
p:=;
rank[sa[,k],k]:=;
for i:= to n do
begin
if (y[sa[i,k]]<>y[sa[i-,k]]) or (y[sa[i,k]+j]<>y[sa[i-,k]+j]) then inc(p);
rank[sa[i,k],k]:=p;
end;
m:=p;
j:=j shl ;
end;
h[,k]:=;
p:=;
for i:= to n do
begin
if rank[i,k]= then continue;
j:=sa[rank[i,k]-,k];
while (i+p<=n) and (j+p<=n) and (s[i+p,k]=s[j+p,k]) do inc(p);
h[rank[i,k],k]:=p;
if p> then dec(p);
end;
for i:= to n do
f[i,,k]:=h[i,k];
for j:= to t do
for i:= to n do
if i+d[j]-<=n then
f[i,j,k]:=min(f[i,j-,k],f[i+d[j-],j-,k])
else break;
end; function ask(l,r,k:longint):longint;
var p:longint;
begin
if l>r then swap(l,r);
inc(l);
p:=trunc(ln(r-l+)/ln()+eps);
exit(min(f[l,p,k],f[r-d[p]+,p,k]));
end; procedure work(l,r:longint);
var mid,i,j,x,y:longint;
begin
if r-l+<m+ then exit;
mid:=(l+r) shr ;
for i:=mid-m+ to mid do
for j:=i- downto l do
begin
if r-(i+m)+<i-j then break;
if ask(rank[j,],rank[i+m,],)>=i-j then inc(ans);
end; for i:=l to mid-m- do
begin
x:=min(ask(rank[i,],rank[mid,],),mid-i-m);
if (x<) then continue;
y:=ask(rank[n+-i,],rank[n+-mid,],);
y:=min(y-,min(i-l,mid-i-m-));
if y<mid-i-m-x then continue;
ans:=ans+min(x,y-(mid-i-m-x)+);
end;
for i:=mid+m+ to r do
begin
y:=min(i-mid-m,ask(rank[n+-i,],rank[n+-mid,],));
if y< then continue;
x:=ask(rank[i+,],rank[mid+,],);
x:=min(x,min(r-i,i-mid-m-));
if x<i-mid-m-y then continue;
ans:=ans+min(y,x-(i-mid-m-y)+);
end;
work(l,mid-);
work(mid+,r);
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) shr ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
swap(b[i],b[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; begin
readln(n,m);
for i:= to n do
read(a[i]);
dec(n);
for i:= to n do
s[i,]:=a[i+]-a[i]; for i:= to n do
begin
a[i]:=s[i,];
b[i]:=i;
end;
sort(,n);
mx:=;
s[b[],]:=;
for i:= to n do
begin
if a[i]<>a[i-] then inc(mx);
s[b[i],]:=mx;
end;
for i:= to n do
s[i,]:=s[n+-i,];
t:=trunc(ln(n)/ln()+eps);
d[]:=;
for i:= to t do
d[i]:=d[i-]*;
suffix();
suffix();
work(,n);
writeln(ans);
end.

bzoj2119的更多相关文章

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

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

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

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

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

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

  4. [NOI2016]优秀的拆分&&BZOJ2119股市的预测

    [NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...

  5. bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...

  6. bzoj2119 [ZJOI2010]base基站选址

    传送门 n年前的考试题,今天才填上…… 听说你们会决策单调性+主席树?然而我多年不写决策单调性,懒得写了……于是就写了一发线段树. 其实线段树应该不难想,毕竟转移是分层转移,并且这个题的转移函数可以快 ...

  7. bzoj2119 股市的预测

    传送门 感觉智商莫名其妙的就变低了……写这题的时候死活想不出来…… 做法其实不难…… 题目要求形如ABA的串的个数,我们可以枚举A的长度,利用标记关键点的方法统计答案.设枚举到的答案为k,每k个点标记 ...

  8. BZOJ2119: 股市的预测(后缀数组)

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

  9. BZOJ2534 Uva10829L-gap字符串 字符串 SA ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9240665.html 题目传送门 - BZOJ2534 题意 有一种形如 $uvu$ 形式的字符串,其中 $u ...

随机推荐

  1. function的prototype

    prototype只有function才有的属性. var a = function() { this.age = 12; this.name = "haha"; }; a.pro ...

  2. 编写单例的 dojo class

    define([ "dojo/_base/declare" ],function( declare ){ var TimeChartService = declare(" ...

  3. C#&java重学笔记(泛型)

    C#部分: 1.泛型的出现主要用于解决类.接口.委托.方法的通用性,通过定义泛型类.接口.委托.方法,可以让不同类型的数据使用相同运算规则处理数据,方便了开发. 2.利用System.Nullable ...

  4. 李洪强iOS开发之OC点语法和变量作用域

    OC点语法和变量作用域 一.点语法 (一)认识点语法 声明一个Person类: 1 #import <Foundation/Foundation.h> 2 3 @interface Per ...

  5. lintcode:最大间隔

    题目 给定一个未经排序的数组,请找出其排序表中连续两个要素的最大间距. 如果数组中的要素少于 2 个,请返回 0. 注意事项 可以假定数组中的所有要素都是非负整数,且最大不超过 32 位整数. 样例 ...

  6. C#的控制台程序输出

    1. int nChar; string mystring; Console.WriteLine("{0} {1}",nChar,mystring); 其中{0},{1}为占位符 ...

  7. Android核心分析之二十Android应用程序框架之无边界设计意图

    Android应用程序框架1 无边界设计理念 Android的应用框架的外特性空间的描述在SDK文档(http://androidappdocs.appspot.com/guide/topics/fu ...

  8. 快笑死,侯捷研究MFC的原因

    与我研究VCL框架代码的原因一模一样:就是N年了,感觉自己还是没有掌握Delphi,惊叹别人各种各样神奇的效果,自己却不会,更不知为什么这样做,离高手的距离还有十万八千里.而且编程的时候,就像侯捷说的 ...

  9. dojo新建widget步骤----主要针对widget路径

    一,新建目录 二,新建文件 三,写urtil widget代码 四,写RedTextDialog代码 五,写HTML代码 =====================如有不懂,结合http://blog ...

  10. jsp中的out对象 和 servlet中的response.getOutputStream()

    web容器生成的servlet代码中有out.write(””),这个和JSP中调用的response.getOutputStream()产生冲突. 即Servlet规范说明,不能既调用 respon ...