2119: 股市的预测

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 404  Solved: 188

Description

墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势。股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况。经过长时间的观测,墨墨发现很多股票都有如下的规律:之前的走势很可能在短时间内重现!如图可以看到这只股票A部分的股价和C部分的股价的走势如出一辙。通过这个观测,墨墨认为他可能找到了一个预测股票未来走势的方法。进一步的研究可是难住了墨墨,他本想试图统计B部分的长度与发生这种情况的概率关系,不过由于数据量过于庞大,依赖人脑的力量难以完成,于是墨墨找到了善于编程的你,请你帮他找一找给定重现的间隔(B部分的长度),有多少个时间段满足首尾部分的走势完全相同呢?当然,首尾部分的长度不能为零。

Input

输入的第一行包含两个整数N、M,分别表示需要统计的总时间以及重现的间隔(B部分的长度)。接下来N行,每行一个整数,代表每一个时间点的股价。

Output

输出一个整数,表示满足条件的时间段的个数

Sample Input

12 4
1 2 3 4 8 9 1 2 3 4 8 9

Sample Output

6
【样例说明】
6个时间段分别是:3-9、2-10、2-8、1-9、3-11、4-12。

HINT

对于100%的数据,4≤N≤50000 1≤M≤10 M≤N 所有出现的整数均不超过32位含符号整数。

Source

【分析】

  做差之后就是UVU式的题,就是像UVA10829那题了。

  所以可以看那个题解。

  然后我觉得我那时候智障。。。while找的话其实nlogn就没用了,变成了n^2,也不知道我当时看谁的。

  但是亲测,一边sa一边while可过,两边while不可过。

  但是太迷了,我把它改成了两边sa了。比之前就快了很多。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxl 50010 int l,pp;
int c[Maxl],cl; int mymin(int x,int y) {return x<y?x:y;} struct node {int x,id;}t[Maxl];
bool cmp(node x,node y) {return x.x<y.x;} void init()
{
scanf("%d%d",&cl,&l);
int bf;
scanf("%d",&bf);
for(int i=;i<=cl;i++)
{
int x;
scanf("%d",&x);
t[i-].x=x-bf;t[i-].id=i-;
bf=x;
}cl--;
sort(t+,t++cl,cmp);
pp=;c[t[].id]=;
for(int i=;i<=cl;i++)
{
if(t[i].x!=t[i-].x) pp++;
c[t[i].id]=pp;
}
} int sa[Maxl],rk[Maxl],y[Maxl],wr[Maxl],Rs[Maxl];
void get_sa(int m)
{
memcpy(rk,c,sizeof(rk));
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int ln=,p=;
while(p<cl)
{
int k=;
for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln;
for(int i=;i<=cl;i++) wr[i]=rk[y[i]]; for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=,rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]]||wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
ln*=,m=p;
}
sa[]=rk[]=;
} int height[Maxl];
void get_he()
{
int k=;
for(int i=;i<=cl;i++) if(rk[i]!=)
{
int j=sa[rk[i]-];
if(k) k--;
while(c[i+k]==c[j+k]&&i+k<=cl&&j+k<=cl) k++;
height[rk[i]]=k;
}
} int d[][Maxl][];
void rmq_init(int p)
{
for(int i=;i<=cl;i++) d[p][i][]=height[i];
for(int j=;(<<j)<=cl;j++)
for(int i=;i+(<<j)-<=cl;i++)
d[p][i][j]=mymin(d[p][i][j-],d[p][i+(<<j-)][j-]);
} int rq[][Maxl];
int rmq(int x,int y,int p)
{
int t;
x=rq[p][x];y=rq[p][y];
if(x>y) swap(x,y);
x++;
int k=;
while((<<k+)<=y-x+) k++;
return mymin(d[p][x][k],d[p][y-(<<k)+][k]);
} void ffind()
{
int ans=;
for(int i=;i<=cl;i++)
{
for(int j=;j<=cl/i;j++)
{
int now=j*i+,x=,y=;
if(now+l+i>cl) continue;
x=mymin(i,rmq(now,now+l+i,));
y=mymin(i-,rmq(cl-(now+l+i-)+,cl-(now-)+,));
if(x+y-i+>&&x!=) ans+=x+y-i+;
}
}
printf("%d\n",ans);
} int cc[Maxl]; int main()
{
init();
get_sa(pp);for(int i=;i<=cl;i++) rq[][i]=rk[i];
get_he();rmq_init();
for(int i=;i<=cl;i++) cc[i]=c[cl-i+];
for(int i=;i<=cl;i++) c[i]=cc[i];
get_sa(pp);
for(int i=;i<=cl;i++) rq[][i]=rk[i];
get_he();
rmq_init();
ffind();
return ;
}

2017-03-24 14:42:24

最新文章

  1. java之对象转型
  2. nodejs weixin 笔记
  3. lbs basic mongodb
  4. 物联网 WIFI 一键配置原理(smartconfig) ESP8266/QCA4004
  5. mysql slow log分析工具的比较
  6. 代码编写横屏的UIView
  7. 计算机原理学习(2)-- 存储器和I/O设备和总线
  8. asp.net core mvc剖析:mvc执行过程(一)
  9. UWP中实现大爆炸效果(一)
  10. ogg 单表拆分合并进程
  11. C# 多线程学习笔记 - 1
  12. innodb 关键特性(insert buffer)
  13. Python request库与爬虫框架
  14. 安装ORACLE高可用RAC集群11g执行root脚本的输出信息
  15. Xen的入门到放弃
  16. Boost中的网络库ASIO,nginx
  17. HP Instant Information
  18. VMware Harbor学习
  19. Mac下如何进行端口转发,方便一系列需要使用80端口进行的调试工作
  20. CentOS使用EPEL YUM源

热门文章

  1. 【BZOJ】3302: [Shoi2005]树的双中心 &amp;&amp; 2103: Fire 消防站 &amp;&amp; 2447: 消防站
  2. BestCoder Round #40 解题报告
  3. tp修改的写法
  4. thinkphp crud实例代码
  5. nginx 配置代理某个路径
  6. python实战===python程序打包成exe
  7. selenium只打开一个浏览器窗口
  8. Swift中的指针类型
  9. caffe Python API 之可视化
  10. 关于angular导入第三方库的问题