SPOJ DISUBSTR Distinct Substrings

每个子串一定是某个后缀的前缀,然后枚举后缀就知道这个后缀能贡献多少个子串,然后height可以查到有多少个重复了,所以累加答案就好了……

/*
 Author : Speedcell
 Update : 2013-10-16
Version : soppYcell 2.4
*/

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <bitset>
#include <memory>
#include <complex>
#include <numeric>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <assert.h>
#include <locale.h>

using namespace std;

#pragma pack(4)

#ifndef __CONSTANT__
#define __CONSTANT__

typedef long long LONG;

const double pi = acos(-1.0);
const int   inf = 0x7f7f7f7f;
const LONG  INF = 0x7f7f7f7f7f7f7f7fll;

const int go[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};

#endif // __CONSTANT__

#ifndef __IO__
#define __IO__

inline bool RD(int    & a) {return scanf("%d",&a)!=EOF;}
inline bool RD(char   & a) {return scanf("%c",&a)!=EOF;}
inline bool RD(char   * a) {return scanf("%s", a)!=EOF;}
inline bool RD(double & a) {return scanf("%lf",&a)!=EOF;}
inline bool RD(LONG   & a) {return scanf("%I64d",&a)!=EOF;}

template<class T1> inline bool
    IN(T1 & a) {return RD(a);}
template<class T1,class T2> inline bool
    IN(T1 & a,T2 & b) {return RD(a)&&RD(b);}
template<class T1,class T2,class T3> inline bool
    IN(T1 & a,T2 & b,T3 & c) {return RD(a)&&RD(b)&&RD(c);}
template<class T1,class T2,class T3,class T4> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d) {return RD(a)&&RD(b)&&RD(c)&&RD(d);}
template<class T1,class T2,class T3,class T4,class T5> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f,T7 & g) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f)&&RD(g);}

inline void PT(int      a) {printf("%d",a);}
inline void PT(char     a) {printf("%c",a);}
inline void PT(char   * a) {printf("%s",a);}
inline void PT(double   a) {printf("%f",a);}
inline void PT(unsigned a) {printf("%u",a);}
inline void PT(LONG     a) {printf("%I64d",a);}
inline void PT(string   a) {printf("%s",a.c_str());}
inline void PT(const char a[]) {printf("%s",a);}

template<class T1> inline void
    OT(T1 a) {PT(a);}
template<class T1,class T2> inline void
    OT(T1 a,T2 b) {PT(a),PT(' '),PT(b);}
template<class T1,class T2,class T3> inline void
    OT(T1 a,T2 b,T3 c) {PT(a),PT(' '),PT(b),PT(' '),PT(c);}
template<class T1,class T2,class T3,class T4> inline void
    OT(T1 a,T2 b,T3 c,T4 d) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d);}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT(' '),PT(g);}

template<class T1> inline void
    OL(T1 a) {OT(a),PT('\n');}
template<class T1,class T2> inline void
    OL(T1 a,T2 b) {OT(a,b),PT('\n');}
template<class T1,class T2,class T3> inline void
    OL(T1 a,T2 b,T3 c) {OT(a,b,c),PT('\n');}
template<class T1,class T2,class T3,class T4> inline void
    OL(T1 a,T2 b,T3 c,T4 d) {OT(a,b,c,d),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e) {OT(a,b,c,d,e),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {OT(a,b,c,d,e,f),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {OT(a,b,c,d,e,f,g),PT('\n');}

#endif // __IO__

#ifndef __MACRO__
#define __MACRO__

#define ML(times) int tcase; IN(tcase); FOR(times,1,tcase)

#define FOR(i,a,b) for(int i=int(a),_##i=int(b);i<=_##i;i++)
#define DWN(i,b,a) for(int i=int(b),_##i=int(a);_##i<=i;i--)
#define ECH(i,u,pre,next) for(int i=int(pre[u]);i!=-1;i=int(next[i]))

#define MEM(a,v) memset(a,v,sizeof(a))
#define CLR(a,v) FOR(_i##a,0,sizeof(a)/sizeof(a[0])-1) a[_i##a]=v

#define LOOP(a,n)                                               \
    FOR(_i##a,0,(n)-1)                                          \
        OT(a[_i##a]),OT(_i##a!=__i##a?' ':'\n')
#define LOOP2(a,n,m)                                            \
    FOR(_i##a,0,(n)-1) FOR(_j##a,0,(m)-1)                       \
        OT(a[_i##a][_j##a]),OT(_j##a!=__j##a?' ':'\n')
#define LOOPG(G,n,pre,next)                                     \
    FOR(_i##a,0,(n)-1) ECH(_j##a,_i##a,pre,next)                \
        OL(_i##a,G[_j##a].v,G[_j##a].w)

#endif // __MACRO__

#ifndef __BIT__
#define __BIT__

template<class T> inline T lb(T i) {return i&-i;}
template<class T> inline T lc(T i) {return i<<1;}
template<class T> inline T rc(T i) {return i<<1|1;}
template<class T> inline T at(T a,int i) {return a& (T(1)<<i);}
template<class T> inline T nt(T a,int i) {return a^ (T(1)<<i);}
template<class T> inline T s1(T a,int i) {return a| (T(1)<<i);}
template<class T> inline T s0(T a,int i) {return a&~(T(1)<<i);}

#endif // __BIT__

#ifndef __COMPARER__
#define __COMPARER__

const double eps = 1e-8;

inline int cmp(double a,double b=0) {return fabs(b-a)<eps?0:((b-a)<eps?+1:-1);}
template<typename type> inline int cmp(type a,type b=0) {return a==b?0:(b<a?+1:-1);}

template<typename type> inline bool gt(type a,type b) {return cmp(a,b)> 0;}
template<typename type> inline bool ge(type a,type b) {return cmp(a,b)>=0;}
template<typename type> inline bool eq(type a,type b) {return cmp(a,b)==0;}
template<typename type> inline bool ne(type a,type b) {return cmp(a,b)!=0;}
template<typename type> inline bool le(type a,type b) {return cmp(a,b)<=0;}
template<typename type> inline bool ls(type a,type b) {return cmp(a,b)< 0;}

template<typename type> inline type smax(type a,type b) {return gt(a,b)?a:b;}
template<typename type> inline type smin(type a,type b) {return ls(a,b)?a:b;}

#endif // __COMPARER__

const int MAXV = 12000;

class SuffixArray
{
private:
	int WA[MAXV],WB[MAXV],WV[MAXV],WS[MAXV];

	#define F(x) ((x)/3+((x)%3==1?0:tb))
	#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)

	int same(int *r,int a,int b)
	{
		return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];
	}
	int c12(int k,int *r,int a,int b)
	{
		if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1);
		else return r[a]<r[b]||r[a]==r[b]&&WV[a+1]<WV[b+1];
	}
	void sort(int *r,int *a,int *b,int n,int m)
	{
		FOR(i,0,n-1) WV[i]=r[a[i]];
		FOR(i,0,m-1) WS[i]=0;
		FOR(i,0,n-1) WS[WV[i]]++;
		FOR(i,0,m-1) WS[i]+=WS[i-1];
		DWN(i,n-1,0) b[--WS[WV[i]]]=a[i];
	}
	void dc3(int *r,int *sa,int n,int m)
	{
		int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
		r[n]=r[n+1]=0;
		FOR(i,0,n-1) if(i%3!=0) WA[tbc++]=i;
		sort(r+2,WA,WB,tbc,m);
		sort(r+1,WB,WA,tbc,m);
		sort(r,WA,WB,tbc,m);
		for(p=1,rn[F(WB[0])]=0,i=1; i<tbc; i++)
			rn[F(WB[i])]=same(r,WB[i-1],WB[i])?p-1:p++;
		if(p<tbc) dc3(rn,san,tbc,p);
		else FOR(i,0,tbc-1) san[rn[i]]=i;
		FOR(i,0,tbc-1) if(san[i]<tb) WB[ta++]=san[i]*3;
		if(n%3==1) WB[ta++]=n-1;
		sort(r,WB,WA,ta,m);
		FOR(i,0,tbc-1) WV[WB[i]=G(san[i])]=i;
		for(i=0,j=0,p=0; i<ta && j<tbc; p++)
			sa[p]=c12(WB[j]%3,r,WA[i],WB[j])?WA[i++]:WB[j++];
		for(; i<ta; p++) sa[p]=WA[i++];
		for(; j<tbc; p++) sa[p]=WB[j++];
	}

	void calheight(int r[],int sa[],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++);
	}
public:
	int sa[MAXV],rank[MAXV],height[MAXV];

	void clear(int a[],int len)
	{
		a[len]=0;
		dc3(a,sa,len+1,*max_element(a,a+len)+1);
		calheight(a,sa,len);
	}
	template<typename type> void display(type a[],int len)
	{
		LOOP(sa,len+1);
		LOOP(rank,len+1);
		FOR(i,1,len)
		{
			OT(height[i],": ");
			FOR(j,sa[i],len-1) OT(a[j]);
			OL("");
		}
	}
}sa;

int b[MAXV];
char a[MAXV];

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("Distinct Substrings.txt","r",stdin);
    #else
    #endif

    ML(times)
    {
    	IN(a);
    	int la=strlen(a);
    	FOR(i,0,la-1) b[i]=a[i];
    	sa.clear(b,la);
    	//sa.display(a,la);
    	int ans=0;
    	FOR(i,1,la)
    	{
    		ans+=(la-sa.sa[i]-sa.height[i]);
    	}
    	OL(ans);
    }

    return 0;
}

你可能感兴趣的:(SPOJ DISUBSTR Distinct Substrings)