• BZOJ 2119 股市的预测 (后缀数组+RMQ)


    题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的

    有点像[NOI2016]优秀的拆分这道题

    先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表

    进入正题

    $ABA$串有一个神奇的性质

    令$A$串长度是$x$

    如果我们选取了一个位置$i$,再选取一个位置$i+x+m$

    用预处理的$st$表,求出经过它们的,最长的相同子串的起始位置$s$和结束位置$e$

    合法的$ABA$串似乎在$[s,e]$之间滑动

    有了这个性质,我们再外层枚举长度$x$,在序列中找出一些相隔为$x$的关键点,求滑动窗口的左$A$串部分,每次当且仅当覆盖一个关键点时,能覆盖的最长距离总和

    总时间$O(n(lnn+logn))$

    别像我一样把RMQ打错还调了20min

      1 #include <map>
      2 #include <cmath>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #define N1 50500
      7 #define ll long long
      8 #define uint unsigned int
      9 #define rint register int 
     10 #define il inline 
     11 #define it map<int,int>::iterator
     12 #define inf 0x3f3f3f3f
     13 using namespace std;
     14 
     15 int gint()
     16 {
     17     int ret=0,fh=1;char c=getchar();
     18     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     19     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     20     return ret*fh;
     21 }
     22 
     23 int n,m,len,nn;
     24 int lg[N1];
     25 struct SA{
     26 int a[N1],tr[N1],rk[N1],hs[N1],sa[N1],h[N1],f[N1][17];
     27 int check(int i,int j,int k){
     28     if(i+k>len||j+k>len) return 0;
     29     return (rk[i]==rk[j]&&rk[i+k]==rk[j+k])?1:0;
     30 }
     31 void Pre()
     32 {
     33     rint i,cnt=0;
     34     for(i=1;i<=len;i++) hs[a[i]]++;
     35     for(i=1;i<=nn;i++) if(hs[i]) tr[i]=++cnt;
     36     for(i=1;i<=nn;i++) hs[i]+=hs[i-1];
     37     for(i=1;i<=len;i++) rk[i]=tr[a[i]],sa[hs[a[i]]--]=i;
     38     for(int k=1;cnt<len;k<<=1)
     39     {
     40         for(i=1;i<=cnt;i++) hs[i]=0;
     41         for(i=1;i<=len;i++) hs[rk[i]]++;
     42         for(i=1;i<=cnt;i++) hs[i]+=hs[i-1];
     43         for(i=len;i>=1;i--) if(sa[i]>k) tr[sa[i]-k]=hs[rk[sa[i]-k]]--;
     44         for(i=1;i<=k;i++)  tr[len-i+1]=hs[rk[len-i+1]]--;
     45         for(i=1;i<=len;i++) sa[tr[i]]=i;
     46         for(i=1,cnt=0;i<=len;i++) tr[sa[i]]=check(sa[i],sa[i-1],k)?cnt:++cnt;
     47         for(i=1;i<=len;i++) rk[i]=tr[i];
     48     }
     49     for(i=1;i<=len;i++){
     50         if(rk[i]==1) continue;
     51         for(int j=max(1,h[rk[i-1]]-1);;j++)
     52             if(a[i+j-1]==a[sa[rk[i]-1]+j-1]) h[rk[i]]=j;
     53             else break;
     54     }
     55     for(i=2;i<=len;i++) f[i][0]=h[i];
     56     for(int j=1;j<=lg[len];j++)
     57         for(i=2;i+(1<<j)-1<=len;i++) 
     58             f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
     59 }
     60 int query(int i,int j){
     61     int x=rk[i],y=rk[j];
     62     if(x>y) swap(x,y);x++;int _L=y-x+1;
     63     if(_L<0) return 0;
     64     return min(f[x][lg[_L]],f[y-(1<<lg[_L])+1][lg[_L]]);
     65 }
     66 }p,s;
     67 int a[N1],A[N1],tmp[N1];
     68 int lower(int l,int r,int *t,int val){
     69     int ans=-inf,id,mid;
     70     while(l<=r){
     71         mid=(l+r)>>1;
     72         if(t[mid]<=val&&t[mid]>ans) ans=t[mid],id=mid,l=mid+1;
     73         else r=mid-1; 
     74     }return id;
     75 }
     76 
     77 int main()
     78 {
     79     scanf("%d%d",&n,&m);
     80     rint i,j;len=n-1;
     81     for(lg[1]=0,i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
     82     A[1]=gint();
     83     for(i=2;i<=n;i++) A[i]=gint(),a[i-1]=tmp[i-1]=A[i]-A[i-1];
     84     sort(tmp+1,tmp+len+1);
     85     nn=unique(tmp+1,tmp+len+1)-(tmp+1);
     86     for(i=1;i<=len;i++) a[i]=lower(1,nn,tmp,a[i]);
     87     for(i=1;i<=len;i++) s.a[i]=a[len-i+1],p.a[i]=a[i];
     88     p.Pre(),s.Pre();
     89     int lx,rx;ll ans=0;
     90     for(j=1;j<=len;j++)
     91     {
     92         for(i=1;i+j+m<=len;i+=j)
     93         {
     94             lx=min(s.query(len-i+1,len-(i+j+m)+1),j);
     95             rx=min(p.query(i+1,i+1+j+m),j-1);
     96             ans+=max(0,lx+rx-j+1);
     97         }
     98     }
     99     printf("%lld
    ",ans);
    100     return 0;
    101 }
    102 /*
    103 2 2 2 3 2 1 2 2 2 3 2
    104 
    105 1 2 2 2 3 2
    106 2
    107 2 1 2 2 2 3 2
    108 2 2 2 3 2
    109 2 2 2 3 2 1 2 2 2 3 2
    110 2 2 3 2
    111 2 2 3 2 1 2 2 2 3 2
    112 2 3 2
    113 2 3 2 1 2 2 2 3 2
    114 3 2
    115 3 2 1 2 2 2 3 2
    116 
    117 2 3 2 2 2 1 2 3 2 2 2
    118 
    119 1 2 3 2 2 2
    120 2
    121 2 1 2 3 2 2 2
    122 2 2
    123 2 2 1 2 3 2 2 2
    124 2 2 2
    125 2 2 2 1 2 3 2 2 2
    126 2 3 2 2 2
    127 2 3 2 2 2 1 2 3 2 2 2
    128 3 2 2 2
    129 3 2 2 2 1 2 3 2 2 2
    130 */
  • 相关阅读:
    node.js 89行爬虫爬取智联招聘信息
    VUE2开发实战——搜索功能
    一个问题一份收获——请求回来的数据应该怎么处理
    JavaScript学习笔记(散)——继承、构造函数super
    讲解版的导航高亮(新手福利)原生JS
    关于node.js和npm,cnpm的安装记录以及gulp自动构建工具的使用
    HTML5中新添加事件
    javascript鸭式辩型法实现接口
    JS原型与原型链终极详解
    Javascript
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10091261.html
Copyright © 2020-2023  润新知