Abelian Period
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others)
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 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 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 .
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 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(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.
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必须是n的因子,又n<10^5,n的因子数不会超过126个(写了个程序试了一下),
所以可以使用枚举k的方法,然后用O(n)的时间检查k是否满足条件。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 100005
int cnt1[N], cnt2[N];
int a[N], n;
bool ok[N];
int check(int i){
memset(cnt1, 0, sizeof(cnt1));
memset(cnt2, 0, sizeof(cnt2));
for(int j = 1; j <= i; j++){
cnt1[a[j]]++;
}
for(int j = 2; j <= n / i; j++){
int l = i*(j-1)+1;
int r = i * j;
for(int k = l; k <= r; k++){
cnt2[a[k]]++;
if(cnt2[a[k]] > cnt1[a[k]])
return 0;
}
for(int k = l; k <= r; k++)
cnt2[a[k]]--;
}
return 1;
}
int main(){
int t, x, ans;
cin>>t;
while(t--){
cin>>n;
memset(ok, false, sizeof(ok));
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= (n>>1); i++){
if(n % i==0 && check(i))
printf("%d ", i);
}
cout<<n<<endl;
}
return 0;
}
开始没想到用暴力,因为n数字太大,感觉会超时。然后看网上大神们有用暴力解的,于是写了个程序测试了一下1~10w
这些数字的因子数,我测的是因子最多126个。而且大部分数的因子不会超过100个,这样看的话,枚举k也是有可能的。