zoukankan      html  css  js  c++  java
  • bzoj2119 股市的预测

    传送门

    感觉智商莫名其妙的就变低了……写这题的时候死活想不出来……

    做法其实不难……

    题目要求形如ABA的串的个数,我们可以枚举A的长度,利用标记关键点的方法统计答案。设枚举到的答案为k,每k个点标记一个关键点,显然每个A只会恰好包含一个关键点,那么我们枚举每个关键点$i$,求一下它和$i+m+l$前后各能匹配到哪儿,显然答案应该加上能匹配的长度。注意为了防止重复计算需要把LCP和LCS(最长公共后缀)对$k$取min。

    求LCP和LCS我是用hash写的,一开始base选的2147483647然后WA了,换成123456789和233333333倒是都能过……什么鬼……

     1 /**************************************************************
     2     Problem: 2119
     3     User: hzoier
     4     Language: C++
     5     Result: Accepted
     6     Time:3664 ms
     7     Memory:1800 kb
     8 ****************************************************************/
     9 #include<cstdio>
    10 #include<cstring>
    11 #include<algorithm>
    12 using namespace std;
    13 const int maxn=50010;
    14 const unsigned long long base=233333333ll;
    15 unsigned long long gethash(int,int);
    16 int LCP(int,int);
    17 int LCS(int,int);
    18 unsigned long long h[maxn],pw[maxn];
    19 long long ans=0;
    20 int n,m,a[maxn];
    21 int main(){
    22     scanf("%d%d",&n,&m);
    23     for(int i=0;i<n;i++)scanf("%d",&a[i]);
    24     for(int i=n;i;i--)a[i]-=a[i-1];
    25     n--;
    26     for(int i=n;i;i--)h[i]=h[i+1]*base+a[i]+base+1ull;
    27     pw[0]=1;
    28     for(int i=1;i<=n;i++)pw[i]=pw[i-1]*base;
    29     for(int l=1;m+(l<<1)<=n;l++){
    30             for(int i=l;i+m+l<=n;i+=l){
    31             int tmpa=min(LCS(i,i+m+l),l),tmpb=min(LCP(i,i+m+l),l);
    32             if(tmpa+tmpb>l)ans+=tmpa+tmpb-l;
    33         }
    34     }
    35     printf("%lld",ans);
    36     return 0;
    37 }
    38 inline unsigned long long gethash(int x,int l){return h[x]-h[x+l]*pw[l];}
    39 int LCP(int x,int y){
    40     if(x>y)swap(x,y);
    41     int L=1,R=n-y+1;
    42     while(L<=R){
    43         int M=(L+R)>>1;
    44         if(gethash(x,M)==gethash(y,M))L=M+1;
    45         else R=M-1;
    46     }
    47     return R;
    48 }
    49 int LCS(int x,int y){
    50     if(x>y)swap(x,y);
    51     int L=1,R=x;
    52     while(L<=R){
    53         int M=(L+R)>>1;
    54         if(gethash(x-M+1,M)==gethash(y-M+1,M))L=M+1;
    55         else R=M-1;
    56     }
    57     return R;
    58 }
    View Code

     

  • 相关阅读:
    linux 制作不用密碼可立即登入的 ssh 用戶
    大部分人都会忽略的Python易错点总结
    Python:有参装饰器与多个装饰器装饰一个函数
    Python面向对象中super用法与MRO机制
    Python实现一个键对应多个值的字典(multidict)
    python中*和**的打包和解包
    面试题:python 中 staticmethod 和 classmethod有什么区别
    Python小练习:StringIO和BytesIO读写操作的小思考
    Python中为什么不能用可变对象作为默认参数的值
    django中csrftoken跨站请求伪造的几种方式
  • 原文地址:https://www.cnblogs.com/hzoier/p/6531800.html
Copyright © 2011-2022 走看看