bzoj2119
题意就是差分后求形如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的更多相关文章
- BZOJ2119 股市的预测 字符串 SA ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/9069171.html 题目传送门 - BZOJ2119 题意 给定一个股票连续$n$个时间点的价位,问有多少段 ...
- 【BZOJ2119】股市的预测 后缀数组+分块
[BZOJ2119]股市的预测 Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰 ...
- 【BZOJ-2119】股市的预测 后缀数组
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 334 Solved: 154[Submit][Status][Discuss ...
- [NOI2016]优秀的拆分&&BZOJ2119股市的预测
[NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...
- bzoj千题计划312:bzoj2119: 股市的预测(后缀数组+st表)
https://www.lydsy.com/JudgeOnline/problem.php?id=2119 题意:将给定数组差分后,求ABA形式的字串个数,要求|B|=m,|A|>0 1.后缀数 ...
- bzoj2119 [ZJOI2010]base基站选址
传送门 n年前的考试题,今天才填上…… 听说你们会决策单调性+主席树?然而我多年不写决策单调性,懒得写了……于是就写了一发线段树. 其实线段树应该不难想,毕竟转移是分层转移,并且这个题的转移函数可以快 ...
- bzoj2119 股市的预测
传送门 感觉智商莫名其妙的就变低了……写这题的时候死活想不出来…… 做法其实不难…… 题目要求形如ABA的串的个数,我们可以枚举A的长度,利用标记关键点的方法统计答案.设枚举到的答案为k,每k个点标记 ...
- BZOJ2119: 股市的预测(后缀数组)
Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工 具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长 ...
- BZOJ2534 Uva10829L-gap字符串 字符串 SA ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/9240665.html 题目传送门 - BZOJ2534 题意 有一种形如 $uvu$ 形式的字符串,其中 $u ...
随机推荐
- JavaScript中this的工作原理以及注意事项
在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this ...
- BeanUtils No value specified for Date的解决方法
/** * ConversionException: No value specified for Date的解决方法 */ ConvertUtils.register(new DateConvert ...
- codeforces 439D Devu and Partitioning of the Array(有深度的模拟)
题目 //参考了网上的代码 注意答案可能超过32位 //要达成目标,就是要所有数列a的都比数列b的要小或者等于 //然后,要使最小的要和最大的一样大,就要移动(大-小)步, //要使较小的要和较大的一 ...
- 思考 ”前端开发人员都在关注的 GitHub 资源“
点这里 原文: 资源 免费的计算机编程类中文书籍 免费编程书籍 计算机科学论文 codeparkshare Python初学者书籍.视频.资料.社区推荐 Python资料汇总 app应用推荐 码农周刊 ...
- Java package详解
Java引入包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突.类文件管理等问题.Java允许将一组功能相关的类放在同一个package下,从而组成逻辑上的类库单元.如果希望把一个 ...
- Es使用。
http://jingyan.baidu.com/article/3052f5a1e8a06397f31f8699.html --------------------------- http://el ...
- C#反射Assembly 详细说明
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- [RM HA 1] Cloudera CDH5 RM HA功能验证
简介: 最新的Cloudera CDH5.0.0 beta版本已经支持RM的HA, 笔者为此简单验证了RM HA的功能. 后续将继续分析其HA的原理,以及其与社区RM HA的区别. 集群部属与RM f ...
- C#获取根目录的方法集合
1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 方法2.AppDomain.Curren ...
- Project Euler 101 :Optimum polynomial 最优多项式
Optimum polynomial If we are presented with the first k terms of a sequence it is impossible to say ...