Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
为什么过不了呢,虽然方法很搓#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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator