标签:
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5769
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <algorithm> using namespace std; const int MAXN = 1e5+7; int t1[MAXN],t2[MAXN],c[MAXN]; bool cmp(int *r,int a,int b,int l) { return r[a] == r[b] && r[a+l] == r[b+l]; } void da(int str[],int sa[],int rankk[],int height[],int n,int m) { n++; int i, j, p, *x = t1, *y = t2; //第一轮基数排序,如果s的最大值很大,可改为快速排序 for(i = 0; i < m; i++) c[i] = 0; for(i = 0; i < n; i++) c[x[i] = str[i]]++; for(i = 1; i < m; i++) c[i] += c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i; for(j = 1; j <= n; j <<= 1) { p = 0; //直接利用sa数组排序第二关键字 for(i = n-j; i < n; i++) y[p++] = i;//后面的j个数第二关键字为空的最小 for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j; //这样数组y保存的就是按照第二关键字排序的结果 //基数排序第一关键字 for(i = 0; i < m; i++)c[i] = 0; for(i = 0; i < n; i++) c[x[y[i]]]++; for(i = 1; i < m; i++) c[i] += c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; //根据sa和x数组计算新的x数组 swap(x,y); p = 1; x[sa[0]] = 0; for(i = 1; i < n; i++) x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++; if(p >= n)break; m = p;//下次基数排序的最大值 } int k = 0; n--; for(i = 0; i <= n; i++)rankk[sa[i]] = i; for(i = 0; i < n; i++) { if(k)k--; j = sa[rankk[i]-1]; while(str[i+k] == str[j+k])k++; height[rankk[i]] = k; } } int rankk[MAXN],height[MAXN]; int RMQ[MAXN]; int mm[MAXN]; int best[20][MAXN]; char str[MAXN]; int r[MAXN]; int sa[MAXN]; int len; int hxpos[MAXN]; int xpos[MAXN]; int main() { int t,cas; __int64 sum; char x[2]; int i,n,cnt; scanf("%d",&t); for(cas=1; cas<=t; cas++) { sum=0; scanf("%s",x); scanf("%s",str); len=strlen(str); memset(xpos,-1,sizeof(xpos)); cnt=0; for(i=0; i<len; i++) { if(str[i]==x[0]) xpos[cnt++]=i; } for( i = 0; i < len; i++)r[i] = str[i]-‘a‘+1; r[len] = 0; da(r,sa,rankk,height,len,30); cnt=0; for(i=0; i<len; i++) { while(xpos[cnt]<i&&xpos[cnt]!=-1) cnt++; if(xpos[cnt]==-1) hxpos[rankk[i]]=len-i+1; else hxpos[rankk[i]]=xpos[cnt]-i+1; } for(i=0; i<len; i++) { sum+=(__int64)(len-sa[i+1]-max(height[i+1],hxpos[i+1]-1)); } printf("Case #%d: %I64d\n",cas,sum); } return 0; }
标签:
原文地址:http://www.cnblogs.com/vwqv/p/5766197.html