Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

为什么过不了呢,虽然方法很搓

Posted by DreamOfGame at 2008-11-17 18:13:08 on Problem 3415
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=210000;

char s[maxn];
int len,k;
int temp;
int sa[maxn],rank[maxn],lcp[maxn];
int left1[maxn],right1[maxn];
int num[maxn];
int k1;
int sa1[200001];
inline bool leq(int a1, int a2, int b1, int b2)
{
    return (a1 < b1 || a1 == b1 && a2 <= b2);
}

inline bool leq(int a1, int a2, int a3, int b1, int b2, int b3)
{
    return(a1 < b1 || a1 == b1 && leq(a2, a3, b2, b3));
}

static void radixPass(int* a, int* b, int* r, int n, int K)
{
    int* c = new int[K + 1];
    int i,sum;
    for(i = 0; i <= K; i++) 
        c[i] = 0;
    for(i = 0; i < n; i++) 
        c[r[a[i]]]++;
    for(i = 0, sum = 0; i <= K; i++)
    {
        int t = c[i]; 
        c[i] = sum; 
        sum += t;
    }
    for(i = 0; i < n; i++) 
        b[c[r[a[i]]]++] = a[i];
    delete [] c;
}

void suffixArray(int* T, int* SA, int n, int K)
{
    int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
    int* R = new int[n02 + 3]; R[n02] = R[n02+1] = R[n02 + 2] = 0;
    int* SA12 = new int[n02 + 3]; SA12[n02] = SA12[n02 + 1] = SA12[n02 + 2] = 0;
    int* R0 = new int[n0];
    int* SA0 = new int[n0];
    int i,j;
    for(i = 0, j = 0; i < n + (n0 - n1); i++) if(i % 3 != 0) R[j++] = i;
    radixPass(R , SA12, T + 2, n02, K);
    radixPass(SA12, R , T + 1, n02, K);
    radixPass(R , SA12, T , n02, K);
    int name = 0, c0 = -1, c1 = -1, c2 = -1;
    
    for( i = 0; i < n02; i++)
    {
        if(T[SA12[i]] != c0 || T[SA12[i] + 1] != c1 || T[SA12[i] + 2] != c2)
        {
            name++; c0 = T[SA12[i]]; c1 = T[SA12[i] + 1]; c2 = T[SA12[i] + 2];
        }
        if(SA12[i] % 3 == 1) { R[SA12[i] / 3] = name; }
        else{ R[SA12[i] / 3 + n0] = name; }
    }
    if(name < n02)
    {
        suffixArray(R, SA12, n02, name);
        for(int i = 0; i < n02; i++) R[SA12[i]] = i + 1;
    }
    else
        for(int i = 0; i < n02; i++) SA12[R[i] - 1] = i;
    for(i = 0, j = 0; i < n02; i++) if(SA12[i] < n0) R0[j++] = 3 * SA12[i];
    radixPass(R0, SA0, T, n0, K);
    for(int p = 0, t = n0 - n1, k = 0; k < n; k++)
    {
        #define GetI() (SA12[t] < n0 ? SA12[t] * 3 + 1 : (SA12[t] - n0) * 3 + 2)
        int i = GetI();
        int j = SA0[p];
        if(SA12[t] < n0 ?
        leq(T[i], R[SA12[t] + n0], T[j], R[j / 3]) : leq(T[i],T[i + 1],R[SA12[t] - n0 + 1], T[j],T[j + 1],R[j / 3 + n0]))
        {
            SA[k] = i; t++;
            if(t == n02)
                for(k++; p < n0; p++, k++) SA[k] = SA0[p];
        }
        else{
            SA[k] = j;
            if(++p == n0)for(k++; t < n02; t++, k++) SA[k] = GetI();
        }
    }
    delete [] R; delete [] SA12; delete [] SA0; delete [] R0;
}

void LCP(char *str,int f[]) 
{ 
    int i,j,k; 
    for(k=i=0;i<len;i++) 
    { 
        if( rank[i] == len - 1 ) lcp[ rank[i] ] = k = 0; 
        else 
        { 
            if( k > 0 )    k--; 
            j = f[ rank[i] + 1]; 
            for(;str[i+k] == str[j+k];k++); 
            lcp[rank[i]] = k; 
        } 
    } 
}

int main(){

    int i, n,p;
    long long answer;
   while(scanf("%d",&p)&&p!=0)
   {
    scanf("%s",s);
    n=strlen(s);
    s[n]='A'-1;
    scanf("%s",s+n+1);
    len=strlen(s);
    //len=2*n+1;
   // for(i=n+1;i<len;i++)
     // s[i]=s[2*n-i];
    for(i=0;i<len;i++)
    {
        num[i]=s[i]-'A'+1;
   //    printf("num[%d]=%d\n",i,num[i]);
    }
    suffixArray(num, sa, len, 60);
    for(i=0;i<len;i++)
        rank[sa[i]]=i;
  
    LCP(s,sa);
   answer=0;
   left1[0]=-1;
   for(i=1;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        temp=i-1;
        while(temp>=0&&lcp[temp]>lcp[i])
         temp=left1[temp];
        left1[i]=temp;
      }
   }
   right1[len-2]=len-1;
   for(i=len-3;i>=0;i--)
   {
      if(lcp[i]>=p)
      {
        temp=i+1;
        while(temp<len-1&&lcp[temp]>=lcp[i])
          temp=right1[temp];
        right1[i]=temp;
      }
   }
   for(i=0;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        answer+=(long long)(lcp[i]-p+1)*((long long)(i-left1[i]-1)*(long long)(right1[i]-i-1)+(long long)right1[i]-(long long)left1[i]-(long long)1);
      }
   } 
   k1=0;
   for(i=0;i<len;i++)
     if(sa[i]>n)
       sa1[k1++]=sa[i]-n-1;
   len=len-n-1;
   for(i=0;i<len;i++)
     rank[sa1[i]]=i;
   LCP(s+n+1,sa1);
   left1[0]=-1;
   for(i=1;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        temp=i-1;
        while(temp>=0&&lcp[temp]>lcp[i])
         temp=left1[temp];
        left1[i]=temp;
      }
   }
   right1[len-2]=len-1;
   for(i=len-3;i>=0;i--)
   {
      if(lcp[i]>=p)
      {
        temp=i+1;
        while(temp<len-1&&lcp[temp]>=lcp[i])
          temp=right1[temp];
        right1[i]=temp;
      }
   }
   for(i=0;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        answer-=(long long)(lcp[i]-p+1)*((long long)(i-left1[i]-1)*(long long)(right1[i]-i-1)+(long long)right1[i]-(long long)left1[i]-(long long)1);
      }
   } 
   len+=(n+1);
   k1=0;
   for(i=0;i<len;i++)
   if(sa[i]<n)
    sa1[k1++]=sa[i];
    len=n;
    for(i=0;i<len;i++)
     rank[sa1[i]]=i;
    LCP(s,sa1);
      left1[0]=-1;
   for(i=1;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        temp=i-1;
        while(temp>=0&&lcp[temp]>lcp[i])
         temp=left1[temp];
        left1[i]=temp;
      }
   }
   right1[len-2]=len-1;
   for(i=len-3;i>=0;i--)
   {
      if(lcp[i]>=p)
      {
        temp=i+1;
        while(temp<len-1&&lcp[temp]>=lcp[i])
          temp=right1[temp];
        right1[i]=temp;
      }
   }
   for(i=0;i<len-1;i++)
   {
      if(lcp[i]>=p)
      {
        answer-=(long long)(lcp[i]-p+1)*((long long)(i-left1[i]-1)*(long long)(right1[i]-i-1)+(long long)right1[i]-(long long)left1[i]-(long long)1);
      }
   } 
    printf("%lld\n",answer);
   }
    return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator