首页 > 代码库 > HDU 5908 Abelian Period(暴力+想法题)
HDU 5908 Abelian Period(暴力+想法题)
传送门
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 i, occ(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 allof these substrings are matched with each other.
Now given a string S, pleasefind 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(1≤T≤10), denoting the number of test cases.
In each test case, the first line of the input contains an integer n(n≤100000),denoting the length of the string.
The second line of the input contains n integers S1,S2,S3,...,Sn(1≤Si≤n), 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
思路
题意:将一个数字串分成长度为k的几个连续区间,如果每个区间内各个元素出现的次数相同,则称k为一个阿贝尔周期,从小到大打印所有阿贝尔周期
可以知道,k必然是n的约数,因此统计每个数出现的次数,求出这些次数的最大公约数,枚举这个最大公约数的约数x,即为可分为的m段,k值即为N/x
#include<bits/stdc++.h>using namespace std;const int maxn = 100005;int gcd(int a,int b){ return b?gcd(b,a%b):a;}int main(){ int T; scanf("%d",&T); while (T--) { int N,a[maxn],cnt[maxn]; memset(cnt,0,sizeof(cnt)); scanf("%d",&N); for (int i = 0;i < N;i++) { scanf("%d",&a[i]); cnt[a[i]]++; } int tmp = cnt[1]; for (int i = 2;i < maxn;i++) tmp = gcd(tmp,cnt[i]); bool first = true; for (int i = tmp;i >= 1;i--) { if (tmp % i == 0) { first?printf("%d",N/i):printf(" %d",N/i); first = false; } } printf("\n"); } return 0;}
HDU 5908 Abelian Period(暴力+想法题)