码迷,mamicode.com
首页 > 其他好文 > 详细

【AHOI2013】差异(2)

时间:2019-08-29 00:18:25      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:space   org   eth   struct   else   for   lan   long   tar   

题面

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;
}

 

【AHOI2013】差异(2)

标签:space   org   eth   struct   else   for   lan   long   tar   

原文地址:https://www.cnblogs.com/shxnb666/p/11427279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!