●BZOJ 2119 股市的预测

题链:

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

题解:

这个题很好的。

首先把序列转化为差分序列,
问题转化为找到合法的子序列,使得去除最中间的 M长度,剩下的头尾完全相同。
枚举重现的长度 len,
然后在序列中每len个长度打一个标记,不难发现,如题所述的A部分一定只包含一个标记点。
然后枚举每个被标记的点 i,得到对应的 j=i+len+M,
然后求出 i和 j 向前向后可匹配的最大长度 L,R
那么对答案的贡献即为 max(0,(min(L-1,len-1)+min(R-1,len-1)+1)-len+1)

要记得离散化。要建两个后缀数组(正逆向)。可以不用long long。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50050
#define filein(x) freopen(#x".in","r",stdin);
#define fileout(x) freopen(#x".out","w",stdout);
using namespace std;
int ta[MAXN],tb[MAXN],cc[MAXN],log2[MAXN];
struct SAY{
	int sa[MAXN],rak[MAXN],hei[MAXN],stm[MAXN][18],*x,*y,h;
	void build(int N,int M,int *a){
		x=ta; y=tb; h=0; a[N]=-1;
		for(int i=0;i<M;i++) cc[i]=0;
		for(int i=0;i<N;i++) cc[x[i]=a[i]]++;
		for(int i=1;i<M;i++) cc[i]+=cc[i-1];
		for(int i=N-1;i>=0;i--) sa[--cc[x[i]]]=i;
		for(int k=1,p;p=0,k<N;k<<=1){
			for(int i=N-k;i<N;i++) y[p++]=i;
			for(int i=0;i<N;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
			for(int i=0;i<M;i++) cc[i]=0;
			for(int i=0;i<N;i++) cc[x[y[i]]]++;
			for(int i=1;i<M;i++) cc[i]+=cc[i-1];
			for(int i=N-1;i>=0;i--) sa[--cc[x[y[i]]]]=y[i];
			swap(x,y); y[N]=-1; x[sa[0]]=0; M=1;
			for(int i=1;i<N;i++)
				x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?M-1:M++;
			if(M>=N) break;
		}
		for(int i=0;i<N;i++) rak[sa[i]]=i;
		for(int i=0,j;i<N;i++){
			if(h) h--;
			if(rak[i]){
				j=sa[rak[i]-1];
				while(a[i+h]==a[j+h]) h++;
			}
			stm[rak[i]][0]=hei[rak[i]]=h;
		}
		for(int k=1;k<=log2[N];k++)
			for(int i=(1<<k)-1;i<N;i++)
				stm[i][k]=min(stm[i-(1<<(k-1))][k-1],stm[i][k-1]);
	}
	int query(int l,int r){
		static int k;
		l=rak[l]; r=rak[r];
		if(l>r) swap(l,r); l++;
		k=log2[r-l+1];
		return min(stm[l+(1<<k)-1][k],stm[r][k]);
	}
}suf1,suf2;
int A[MAXN],B[MAXN],tmp[MAXN];
int N,ANS,cnt,D;
int main()
{
	scanf("%d%d",&N,&D);
	log2[1]=0; for(int i=2;i<=50000;i++) log2[i]=log2[i>>1]+1;
	for(int i=0;i<N;i++) scanf("%d",&A[i]);
	for(int i=0;i<N-1;i++) A[i]=A[i+1]-A[i],tmp[i]=A[i]; N--;
	sort(tmp,tmp+N); cnt=unique(tmp,tmp+N)-tmp;
	for(int i=0;i<N;i++) A[i]=lower_bound(tmp,tmp+cnt,A[i])-tmp;
	suf1.build(N,N+10,A);
	for(int i=0;i<N;i++) B[N-1-i]=A[i];
	suf2.build(N,N+10,B);
	for(int len=1,L,R;len<N/2;len++)
		for(int i=0,j;i<N;i+=len){
			j=i+len+D; if(j>=N) break;
			L=suf1.query(i,j);
			R=suf2.query(N-1-i,N-1-j);
			ANS+=max(0,min(L-1,len-1)+min(R-1,len-1)+1-len+1);
		}
	printf("%d",ANS);
	return 0;
}
时间: 2024-08-08 15:18:08

●BZOJ 2119 股市的预测的相关文章

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

2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 331  Solved: 153[Submit][Status][Discuss] Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时间的观测,墨墨发现很多股票都有如下的规律:之前的走势很可能在短时间内重现!如图可以看到这只股票A

BZOJ 2119: 股市的预测 SA

2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 434  Solved: 200[Submit][Status][Discuss] Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时间的观测,墨墨发现很多股票都有如下的规律:之前的走势很可能在短时间内重现!如图可以看到这只股票A

BZOJ 2119: 股市的预测

Description 求形如ABA形式的字符串,其中B长度固定,\(n\leqslant 10^5\) Solution 后缀数组. 我们可以枚举一个长度\(x\),然后将序列分组,每组长度为\(x\),然后从\(i\)找和\(i+x+B\)的最长公共后缀和最长公共前缀,然后得到一组合法区间,限制一下在块中防止重复即可. 复杂度就是调和级数. 复杂度\(O(nlogn)\) Code /******************************************************

BZOJ 2119 股市的预测 后缀数组

题目大意:给定一个序列,求差分后有多少个子串满足形式为ABA,其中B部分长度为m,A部分长度大于0 首先枚举A的长度j,将序列上每隔j个点插入一个关键点 对于第i个位置上的关键点,我们找到第i+j+m个位置 利用后缀数组找出两个位置向左拓展多少个位置都是相同的,以及向右拓展都少个位置都是相同的 为了保证不重复向左和向右最多拓展j-1个位置 设拓展之后长度为len,那么如果len>=j,ans+=(len-j+1) 如图,拓展出的区域长度为5,j=4,则可以找到两个子串 其中两个a虽然相同,但是由

bzoj2119 股市的预测

bzoj 题解: 后缀数组+RMQ 有一个性质是,若出现ABA形式,且|A|比较大|B|<=m,那么真正的B块端点可以来回滑动. 因此我们可以正反做两遍后缀数组,利用RMQ求出区间最小值即前缀长. 然后先枚举|A|,再枚举左边A的端点,这样ABA位置大体确定. 然后在两个左端点处分别向两端延伸,更新答案. 时间复杂度O(nlnn)? 代码: #include<cmath> #include<cstdio> #include<cstring> #include<

股市潜规则 你经历过几个?(转)

1.看好不买一直涨,追涨买后变熊样! 2.气愤不过卖掉:卖后立即涨! 3.两选一必然选错,买的下跌,没买的大涨! 4.选错后改正错误,换股,又换错! 5.下决心不搞短线,长期持股,则长期不涨! 6.抛了长线,第二天涨停! 7.又去搞短线,立即被套! 8.给别人推荐的涨,自己手里的跌. 点评:股票是风险性资产,因此股票投资者在做投资决策之前,必须衡量自己承担风险的能力,以免遭受过度的损失,或破坏了这一市场的信用. 网友声音—— 溪水金桥:读完这8句话,发现都在我身上发生过.按说应该悲催了,可我边读

股市集合竞价藏了很多秘密

一.9:15----9:20这五分钟开放式集合竞价可以委托买进和卖出的单子,你看到的匹配成交量可能是虚假的,因这5分钟是可以撤单,很多主力在9:19:30左右撤单,当你买进时,你不撤单,他可撤出,然后他卖给你,因此你一定要把撤单键放在手上. 二.9:20---9:25这五分钟开放式集合竞价可以输委托买进和卖出的单子,但不能撤单,有的投资者认为他己撤单就完事了,事实上这五分钟撤单是无效的.这五分钟你看到的委托是真实的,因此要抢涨停板的,一定要看准这五分钟,但你不知道这五分钟哪些股票要涨停板,利用按

提升大数据数据分析性能的方法及技术(二)

上部分链接 致谢:因为我的文章之前是在word中写的,贴过来很多用mathtype编辑的公式无法贴过来,之前也没有经验. 参考http://www.cnblogs.com/haore147/p/3629895.html,一文完成公式的迁移. 同时,说一句,word中用mathtype写的公式用ALT+\可以转换成对应的latex语法公式. 5 数据流过滤技术 信息大爆炸时代的到来使得针对数据进行深层次的挖掘成为数据处理的核心任务[21].但是在上面已经提到了,源数据的来源和数据的组成格式都是各种

巴菲特

1.一生能够积累多少财富,不取决于你能够赚多少钱,而取决于你如何投资理财,钱找人胜过人找钱,要懂得钱为你工作,而不是你为钱工作. 2.那些最好的买卖,刚开始的时候,从数字上看,几乎都会告诉你不要买. 3.我们之所以取得目前的成就,是因为我们关心的是寻找那些我们可以跨越的一英尺障碍,而不是去拥有什么能飞越七英尺的能力. 4.在别人恐惧时我贪婪,在别人贪婪时我恐惧. 5.如果你不愿意拥有一只股票十年,那就不要考虑拥有它十分钟. 6.拥有一只股票,期待它下个早晨就上涨是十分愚蠢的. 7.永远不要问理发