zoukankan      html  css  js  c++  java
  • 【AHOI2013】差异(2)

    题面

    https://www.luogu.org/problem/P4248

    题解

    这里,提供后缀数组的做法。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    const int N=1000050;
    using namespace std;
    char s[N];
    int n,m,rank[N],sa[N],tax[N],tp[N],height[N];
    struct rmq {
      int minh,loc;
    } r[N][25];
    long long sum[N];
    long long ans=0;
    
    void cntsort(){
      for (int i=0;i<=m;i++) tax[i]=0;
      for (int i=1;i<=n;i++) tax[rank[i]]++;
      for (int i=1;i<=m;i++) tax[i]+=tax[i-1];
      for (int i=n;i>=1;i--) sa[tax[rank[tp[i]]]--]=tp[i];
    }
    
    void suffixsort(){
      m=75;
      for (int i=1;i<=n;i++) rank[i]=s[i]-'0'+1,tp[i]=i;
      cntsort();
      for (int w=1,p=0;p<n;m=p,w<<=1) {
        p=0;
        for (int i=1;i<=w;i++) tp[++p]=n-w+i;
        for (int i=1;i<=n;i++) if (sa[i]>w) tp[++p]=sa[i]-w;
        cntsort();
        swap(tp,rank);
        rank[sa[1]]=p=1;
        for (int i=2;i<=n;i++) 
          rank[sa[i]]=(tp[sa[i-1]]==tp[sa[i]] && tp[sa[i-1]+w]==tp[sa[i]+w]) ? p:++p;
      }
    }
    void getheight(){
      int k=0;
      for (int i=1;i<=n;i++) {
        if (k) k--;
        int j=sa[rank[i]-1];
        while (s[i+k]==s[j+k]) k++;
        height[rank[i]]=k;
      }
    }
    
    void getsum(){
      int i;
      sum[0]=0;
      for (i=1;i<=n;i++) sum[i]=sum[i-1]+n-sa[i]+1;
    }
    
    void getrmq(){
      int i,j;
      for (i=1;i<=n;i++) r[i][0]=(rmq){height[i],i};
      for (i=1;i<=20;i++) {
        int l=(1<<i);
        for (j=1;j<=n;j++) if (r[j][i-1].minh<r[j+l/2][i-1].minh) r[j][i]=r[j][i-1]; else r[j][i]=r[j+l/2][i-1];
      }
    }
    
    void solve(int L,int R){
      int i,minh=0x7f7f7f7f,p,mid=L+R>>1;
      int len=1,cnt=0;
      while (len<=R-L+1) len*=2,cnt++;
      len/=2; cnt--;
      rmq r1=r[L][cnt],r2=r[R-len+1][cnt];
      if (r1.minh<r2.minh) {
          p=r1.loc;
          minh=r1.minh;
      }
      else {
          p=r2.loc;
          minh=r2.minh;
      }
      long long sum1=sum[p-1]-sum[L-2],sum2=sum[R]-sum[p-1];
      ans+=sum1*(R-p+1)+sum2*(p-L+1)-2*(R-p+1)*1LL*(p-L+1)*minh;
      if (L<=p-1) solve(L,p-1);
      if (p+1<=R) solve(p+1,R);
    }
    
    int main(){
      scanf("%s",s+1);
      n=strlen(s+1);
      suffixsort();
      getheight();
      getsum();
      getrmq();
      solve(2,n);
      cout<<ans<<endl;
      return 0;
    }
  • 相关阅读:
    spring整合mybatis的事物管理配置
    平庸久了,是会上瘾的
    kafka基本概念
    JMS编程模型
    aop的基本概念
    事务的隔离级别和传播行为
    IntelliJ IDEA 导入Project
    [PowerShell]列出檔案與資料夾的資訊
    [powershell]统计目录大小
    [powershell]有关IP的设置
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427279.html
Copyright © 2011-2022 走看看