Zoj Thousand Questions Plan 314: bzoj3238: [Ahoi2013] Difference (suffix array + st table + monotonic stack)

https://www.lydsy.com/JudgeOnline/problem.php?id=3238

 

Similar to bzoj3879

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 500001

int n,m,mm;
char s[N];
int a[N];

int v [N];
int p, q = 1 , k;
int sa [ 2 ] [N], rk [ 2 ] [N];

int h[N];
int st[N][16];

int Log[N];

int ST[N],top;
int num[N],val[N];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

void mul ( int * sa, int * rk, int * SA, int * RK)
{
    for ( int i = 1 ; i <= n; ++ i) v [rk [sa [i]]] = i;
    for ( int i = n; i;-i) if (sa [i]> k) SA [v [rk [sa [i] -k]]-] = sa [i] -k;
    for ( int i = n-k+ 1 ; i <= n; ++ i) SA [v [rk [i]]-] = i;
    for ( int i = 1 ; i <= n; ++ i) RK [SA [i]] = RK [SA [i- 1 ]]+(rk [SA [i]]! = rk [SA [i- 1 ]] || rk [SA [i]+ k]! = Rk [SA [i- 1 ]+ k]);
}

void dam ()
{
    for(int i=1;i<=n;++i) v[a[i]]++;
    for(int i=1;i<=26;++i) v[i]+=v[i-1];
    for(int i=1;i<=n;++i) sa[p][v[a[i]]--]=i;
    for(int i=1;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
    for(k=1;k<n;k<<=1,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]);
}

void get_height()
{
    int k=0,j;
    for(int i=1;i<=n;++i)
    {
        j=sa[p][rk[p][i]-1];
        while(a[i+k]==a[j+k]) k++;
        h[rk[p][i]]=k;
        if(k) k--;
    }
}

void prest()
{
    for(int i=2;i<=n;++i) st[i][0]=h[i];
    for(int i=1,k=2;i<=15;++i,k<<=1)
        for(int j=2;j+k-1<=n;++j) 
            st[j][i]=min(st[j][i-1],st[j+k/2][i-1]);
}

int get(int i,int j)
{
    i++;
    int l=Log[j-i+1];
    return min(st[i][l],st[j-(1<<l)+1][l]);
}

void solve()
{
    top=0;
    int tmp_num;
    long long now=0,ans=0;
    for(int i=2;i<=n;++i)
    {
        tmp_num=0;
        while(top && h[i]<=h[ST[top]]) 
        {
            now-=1LL*num[top]*val[top];
            tmp_num+=num[top--];
        }
        tmp_num++;
        ST[++top]=i;
        num[top]=tmp_num;
        val[top]=h[i];
        now+=1LL*tmp_num*h[i];
        ans+=now;
    }
    years = -years* 2 ;
    ans +=1LL*n*(n+ 1 )/ 2 *(n- 1 );
    cout<<ans<<'\n';
}

intmain ()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=2;i<=n;++i) Log[i]=Log[i>>1]+1;
    for(int i=1;i<=n;++i) a[i]=s[i]-'a'+1;
    the press();
    get_height();
    perst ();
    solve();
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325126315&siteId=291194637