spoj 705. New Distinct Substrings

来源:互联网 发布:centos 搜狗输入法 编辑:程序博客网 时间:2024/05/11 22:38

题目链接:http://www.spoj.pl/problems/SUBST1/

题目思路:直接求反面,容易发现不同子串个数,是总个数减去所有height[i]的和。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>//#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define M 110000int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int sa[M],height[M],rank[M];int wa[M],wb[M],wv[M],ws[M],r[M];bool cmp(int *y,int a,int b,int l){    return y[a]==y[b]&&y[a+l]==y[b+l];}void da(int n,int m){    int i,j,p;    int *x=wa,*y=wb;    for(i=0;i<m;i++) ws[i]=0;    for(i=0;i<n;i++) ws[x[i]=r[i]]++;    for(i=1;i<m;i++) ws[i]+=ws[i-1];    for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;    for(j=1,p=1;p<n;j*=2,m=p)    {        p=0;        for(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<m;i++) ws[i]=0;        for(i=0;i<n;i++) wv[i]=x[y[i]];        for(i=0;i<n;i++) ws[wv[i]]++;        for(i=1;i<m;i++) ws[i]+=ws[i-1];        for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];        swap(x,y);        x[sa[0]]=0;        p=1;        for(i=1;i<n;i++)        {            if(cmp(y,sa[i-1],sa[i],j)) x[sa[i]]=p-1;            else x[sa[i]]=p++;        }    }}void calh(int n){    int i,k;    for(i=1;i<=n;i++) rank[sa[i]]=i;    k=0;    for(i=0;i<n;i++)    {        int tmp=sa[rank[i]-1];// puts("akkkk");       // printf("tmp %d\n",tmp);        for(;r[i+k]==r[tmp+k];k++)        ;        height[rank[i]]=k;      //  printf("i %d h %d\n",i,height[rank[i]]);        k?--k:0;    }}char s[M];int main(){    int i,t,n;    long long ans;    scanf("%d",&t);    while(t--)    {        scanf("%s",s);        n=strlen(s);        for(i=0;i<n;i++)            r[i]=s[i];        r[n]=0;        da(n+1,200);     //   printf("akk\n");        calh(n);      //   for(i=1;i<=n;i++)     //   {      //      printf("i %d h %d sa %d\n",i,height[i],sa[i]);     //   }        ans=(long long )n*(n+1)/2;        for(i=1;i<=n;i++)        {            ans-=height[i];        }        printf("%lld\n",ans);    }}


 

原创粉丝点击