【hdoj5908】Abelian Period

Abelian Period

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)
Total Submission(s): 602    Accepted Submission(s): 253


Problem Description
Let S be a number string, and occ(S,x) means the times that number x occurs in S.

i.e. S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1.

String u,w are matched if for each number iocc(u,i)=occ(w,i) always holds.

i.e. (1,2,2,1,3)(1,3,2,1,2).

Let S be a string. An integer k is a full Abelian period of S if S can be partitioned into several continous substrings of length k, and all of these substrings are matched with each other.

Now given a string S, please find all of the numbers k that k is a full Abelian period of S.
 

Input
The first line of the input contains an integer T(1T10), denoting the number of test cases.

In each test case, the first line of the input contains an integer n(n100000), denoting the length of the string.

The second line of the input contains n integers S1,S2,S3,...,Sn(1Sin), denoting the elements of the string.
 

Output
For each test case, print a line with several integers, denoting all of the number k. You should print them in increasing order.
 

Sample Input
2 6 5 4 4 4 5 4 8 6 5 6 5 6 5 5 6
 

Sample Output
3 6 2 4 8
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5921 5920 5919 5918 5917 
 

題目大意:給你n個數,輸出所有的長度使得每段該長度的數字出現的次數相同。


首先,該數必須能被n整除才能出現每個數據段各個數字相等的情況。然後考慮,先統計各個數字出現的總個數,這樣每個數字在每個數據段出現的次數唯一確定,寫一個判斷函數判斷是否每個數據段中的數字都等於該唯一確定的數即可。是輸出,否跳過。286ms

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 500000+20;
int ant[N],rec[N],a[N];
int tol,n;
bool judge(int k) {
	int cnt=n/k;
	memset(ant,0,sizeof(ant));
	for(int i=0; i<cnt; i++) {
		int flag=0;
		for(int j=1; j<=k; j++) {
			ant[a[i*k+j]]++;
			if(ant[a[i*k+j]]*cnt>rec[a[i*k+j]]*(i+1))
				return false;
			else if(ant[a[i*k+j]]*cnt==rec[a[i*k+j]]*(i+1))
				flag++;
		}
		if(flag!=tol)
			return false;
	}
	return true;
}
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		scanf("%d",&n);
		memset(rec,0,sizeof(rec));
		for(int i=1; i<=n; i++) {
			scanf("%d",&a[i]);
			rec[a[i]]++;
		}
		tol=0;
		for(int i=1; i<N; i++) {
			if(rec[i])
				tol++;
		}
		for(int i=1; i*2<=n; i++) {
			if(n%i==0) {
			//	printf("--\n");
				if(judge(i)) {
					printf("%d ",i);
				}
			}
		}
		printf("%d\n",n);
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章