Repeats SPOJ - REPEATS(鍚庣紑鏁扮粍瑙e喅閲嶅娆℃暟鏈€澶氱殑杩炵画閲嶅瀛愪覆)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Repeats SPOJ - REPEATS(鍚庣紑鏁扮粍瑙e喅閲嶅娆℃暟鏈€澶氱殑杩炵画閲嶅瀛愪覆)相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/cal' title='cal'>cal   char   鍏叡鍓嶇紑   +=   scanf   --   char s   poj   鎯呭喌   

棰樼洰閾炬帴
棰樻剰锛氱粰瀹氫竴涓瓧绗︿覆锛屾眰閲嶅娆℃暟鏈€澶氱殑杩炵画閲嶅瀛愪覆
棰樼洰鎬濊矾锛氬厛绌蜂妇闀垮害L锛岀劧鍚庢眰闀垮害涓篖鐨勫瓙涓叉渶澶氳兘杩炵画鍑虹幇鍑犳銆傞鍏堣繛缁嚭鐜?娆℃槸鑲畾鍙互鐨勶紝鎵€浠ヨ繖閲屽彧鑰冭檻鑷冲皯2娆$殑鎯呭喌銆傚亣璁惧湪鍘熷瓧绗︿覆涓繛缁嚭鐜?娆★紝璁拌繖涓瓙瀛楃涓蹭负S锛岄偅涔圫鑲畾鍖呮嫭浜嗗瓧绗[0], r[L], r[L2],r[L3], 鈥︹€︿腑鐨勬煇鐩搁偦鐨勪袱涓€傛墍浠ュ彧椤荤湅瀛楃r[Li]鍜宺[L(i+1)]寰€鍓嶅拰
寰€鍚庡悇鑳藉尮閰嶅埌澶氳繙锛岃杩欎釜鎬婚暱搴︿负K锛岄偅涔堣繖閲岃繛缁嚭鐜颁簡K/L+1娆°€傛渶鍚庣湅鏈€澶у€兼槸澶氬皯銆?br> 绌蜂妇闀垮害L鐨勬椂闂存槸n锛屾瘡娆¤绠楃殑鏃堕棿鏄痭/L銆傛墍浠ユ暣涓仛娉曠殑鏃堕棿澶嶆潅搴︽槸O(n/1+n/2+n/3+鈥︹€?n/n)=O(nlogn)銆?br> 鐢≧MQ棰勫鐞嗗尯闂存渶灏忓€硷紝鏂逛究姹俽[Li]鍜宺[L(i+1)]鐨勬渶闀垮叕鍏卞墠缂€锛岃繖灏辨槸寰€鍚庨潰鍖归厤浜嗗闀裤€?br> 瀵逛簬寰€鍓嶉潰鍖归厤浜嗗闀匡紝鎴戜滑鍙鐪媕L-(i-k%i)鍜?j+1)L-(i-k%i)鑳藉惁绠椾笂鍘诲嵆鍙€?/p>

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define Max_N 50010
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) 
int wa1[Max_N*3], wb1[Max_N*3], wv1[Max_N*3], ws1[Max_N*3]; 
int c0(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] && wv1[a+1] < wv1[b+1];
}
    
 void sort(int *r, int *a, int *b, int n, int m) 
 { 
	int i; 
	for (i = 0; i < n; i++) wv1[i] = r[a[i]]; 
	for (i = 0; i < m; i++) ws1[i] = 0; 
	for (i = 0; i < n; i++) ws1[wv1[i]]++; 
	for (i = 1; i < m; i++) ws1[i] += ws1[i-1]; 
	for (i = n-1; i >= 0; i--) b[--ws1[wv1[i]]] = a[i]; 
	return; 
 }
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; i < n; i++) if (i % 3 != 0) wa1[tbc++] = i; 
    sort(r+2, wa1, wb1, tbc, m); 
    sort(r+1, wb1, wa1, tbc, m); 
    sort(r, wa1, wb1, tbc, m); 
    for (p = 1,rn[F(wb1[0])] = 0,i = 1;i < tbc; i++) 
    rn[F(wb1[i])] = c0(r, wb1[i-1], wb1[i]) ? p - 1 : p++; 
    if (p < tbc) dc3(rn, san, tbc, p); 
    else for (i = 0; i < tbc; i++) san[rn[i]] = i;
    for (i = 0; i < tbc; i++) if (san[i] < tb) wb1[ta++] = san[i] * 3; 
    if (n % 3 == 1) wb1[ta++] = n - 1; 
    sort(r, wb1, wa1, ta, m); 
    for (i = 0; i < tbc; i++) wv1[wb1[i] = G(san[i])] = i; 
    for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++) 
    sa[p] = c12(wb1[j] % 3, r, wa1[i], wb1[j]) ? wa1[i++] : wb1[j++]; 
    for(; i < ta; p++) sa[p] = wa1[i++]; 
    for(; j < tbc; p++) sa[p] = wb1[j++]; 
    return; 
}
// str sa 閮借寮€涓夊€嶇殑锛?void da(int str[], int sa[], int rank1[], int height1[], int n, int m)
{
	for (int i = n; i < n*3; i++)
		str[i] = 0;
	dc3(str, sa, n+1, m);
	int i, j, k = 0;
	for (i = 0; i <= n; i++) rank1[sa[i]] = i;
	for (i = 0; i < n; i++)
	{
		if (k) k--;
		j = sa[rank1[i] - 1];
		while (str[i+k] == str[j+k]) k++;
		height1[rank1[i]] = k;
	}
	return;
}
int a[Max_N];
int str[3*Max_N];
int sa[3*Max_N];//sa[i]琛ㄧず灏嗘墍鏈夊悗缂€鎺掑簭鍚庣i灏忕殑鍚庣紑鐨勭紪鍙枫€?int rank1[3*Max_N];//rank1[i]琛ㄧず鍚庣紑i鐨勬帓鍚嶃€?int height1[3*Max_N]; //LCP(sa[i],sa[i-1]);
int n;
int minnum[Max_N][16];
void RMQ()   		//棰勫鐞? O(nlogn)
{
	int i,j;
	int m=(int)(log(n*1.0)/log(2.0));
	for(i=1;i<=n;i++)
		minnum[i][0]=height1[i];
	for(j=1;j<=m;j++)
		for(i=1;i+(1<<j)-1<=n;i++)
			minnum[i][j]=min(minnum[i][j-1],minnum[i+(1<<(j-1))][j-1]);
}
int Ask_MIN(int a,int b) 	//O(1)
{
	int k=int(log(b-a+1.0)/log(2.0));
	return min(minnum[a][k],minnum[b-(1<<k)+1][k]);
}
int calprefix(int a,int b)
{
    a=rank1[a],b=rank1[b];
    if(a>b)
        swap(a,b);
    return Ask_MIN(a+1,b);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		char s[5];
		for(int i=0;i<n;i++)
		{
			scanf("%s",s);
			str[i]=s[0]-鈥榓鈥?1;
		}
		str[n]=0;
		da(str, sa, rank1, height1, n, 5);
		RMQ();
		int ans,Max=1;
		for(int i=1;i<=n;i++)
        {
            for(int j=0;j+i<n;j+=i)
            {
                ans=calprefix(j,j+i);
                int k=j-(i-ans%i);
                ans=ans/i+1;
                if(k>=0&&calprefix(k,k+i)>=i)
                    ans++;
                Max=max(Max,ans);
            }
        }
        printf("%d
",Max);
	 } 
 }       



以上是关于Repeats SPOJ - REPEATS(鍚庣紑鏁扮粍瑙e喅閲嶅娆℃暟鏈€澶氱殑杩炵画閲嶅瀛愪覆)的主要内容,如果未能解决你的问题,请参考以下文章

Repeats SPOJ - REPEATS (AC自动机 + RMQ)

SPOJ REPEATS - Repeats - 后缀数组

SPOJ REPEATS - Repeats(后缀数组[重复次数最多的连续重复子串])

SPOJ REPEATS - Repeats(后缀数组[重复次数最多的连续重复子串])

SPOJ Repeats(后缀数组+RMQ)

SPOJ - REPEATS RMQ?????????