HDU 4691 Front compression

後綴數組模板。

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 100005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
const int  mod = 1e9 + 7;


int sa[M] , rank[M] , height[M];
int wa[M] , wb[M] , wv[M] , wd[M];

int cmp(int *r , int a , int b , int l)
{
    return r[a] == r[b] && r[a+l] == r[b+l];
}

void da(int *r , int n , int m)
{
    int i , j , p , *x = wa , *y = wb , *t;
    for (i = 0 ; i < m ; i++)wd[i] = 0;
    for (i = 0 ; i < n ; i++)wd[x[i]=r[i]]++;
    for (i = 1 ; i < m ; i++)wd[i] += wd[i-1];
    for (i = n-1 ; i >= 0 ; i--) sa[--wd[x[i]]] = i;
    for (j = p = 1 ; p < n ; j *= 2 , m = p)
    {
        for (p = 0 , i = n-j ; i < n ; i++)y[p++] = i;
        for (i = 0 ; i < n ; i++)if (sa[i] >= j)y[p++] = sa[i]-j;
        for (i = 0 ; i < n ; i++)wv[i] = x[y[i]];
        for (i = 0 ; i < m ; i++)wd[i] = 0;
        for (i = 0 ; i < n ; i++)wd[wv[i]]++;
        for (i = 1 ; i < m ; i++)wd[i] += wd[i-1];
        for (i = n-1 ; i >= 0 ; i--)sa[--wd[wv[i]]] = y[i];
        for (t = x , x = y , y = t , p = 1 , x[sa[0]] = 0 , i  = 1 ; i < n ; i++)
        x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
}

void calheight(int *r , int n)
{
    int i , j , k = 0;
    for (i = 1 ; i <= n ; i++) rank[sa[i]] = i;
    for (i = 0 ; i < n ; height[rank[i++]] = k)
    for (k?k--:0,j = sa[rank[i]-1] ; r[i+k] == r[j+k] ; k++);
}

char str[M];
int r[M];
int dp[M][20] , LOG[M];

void Init(int n)
{
    int i , j , k;
    for (i = 1 ; i <= n ; i++)dp[i][0] = height[i];
    for (i = 1 ; i <= LOG[n] ; i++)
    {
        for (j = 1 ; j+(1<<i)-1 <= n ; j++)
        {
            dp[j][i] = min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
        }
    }
}

int Query(int l , int r)
{
    int k = LOG[r-l+1];
    return min(dp[l][k],dp[r-(1<<k)+1][k]);
}

int Judge(int k)
{
    int ret = 0;
    while (k)
    {
        ret++;
        k /= 10;
    }
    return ret ? ret : 1;
}

int main()
{
    int i;
    for (LOG[0] = -1 , i = 1 ; i < M ; i++)LOG[i] = LOG[i>>1]+1;
    while (~scanf("%s",str))
    {
        int len = strlen(str);
        for (i = 0 ; i < len ; i++)r[i] = str[i]-'a'+1;
        r[len] = 0;
        da(r,len+1,28);
        calheight(r,len);
        Init(len);
        int m;
        scanf("%d",&m);
        int px , py , nx , ny;
        scanf("%d%d",&px,&py);
        ll ans1 = 0 , ans2 = 0;
        ans1 += py-px+1;
        ans2 += py-px+3;
        int temp;
        while (--m)
        {
            scanf("%d%d",&nx,&ny);
            if (px == nx)temp = min(py-px,ny-nx);
            else
            {
                int l = rank[px] , r = rank[nx];
                if (l > r)swap(l,r);
                temp = Query(l+1,r);
                temp = min(temp,min(py-px,ny-nx));
            }
            ans1 += ny-nx+1;
            ans2 += ny-nx-temp+2+Judge(temp);
            py = ny;
            px = nx;
        }
        printf("%I64d %I64d\n",ans1,ans2);
    }
    return 0;
}


 

發佈了98 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章