Abelian Period
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 524 Accepted Submission(s): 222
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 ,
i.e. (1,2,2,1,3)≈(1,3,2,1,2) .
Let S be a string. An integer
Now given a 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
2
6
5 4 4 4 5 4
8
6 5 6 5 6 5 5 6
3 6
2 4 8
设
例如: S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1 。
如果对于任意的
i
,都有
例如: (1,2,2,1,3)≈(1,3,2,1,2) 。
对于一个数字串
S
和一个正整数
给定一个数字串 S ,请找出它所有的完全阿贝尔周期。
输入的第一行包含一个正整数
对于每组数据,第一行包含一个正整数 n(n≤100000) ,表示数字串的长度。
第二行包含
n
个正整数
对于每组数据,输出一行若干个整数,从小到大输出所有合法的 k 。
2 6 5 4 4 4 5 4 8 6 5 6 5 6 5 5 6
3 6 2 4 8
解题思路:
首先我们可以进行分割的话,一定是分的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <bitset>
#include <map>
using namespace std;
typedef long long LL;
const LL MAXN = 1e5+5;
LL a[MAXN];
LL fac[MAXN];
map<LL,LL>mp1;
map<LL,LL>mp2;
LL ans[MAXN];
int main()
{
LL T;
scanf("%lld",&T);
while(T--){
LL n;
scanf("%lld",&n);
LL cnt = 0;
for(LL i=1; i*i<=n; i++){
if(n % i == 0){
if(i*i != n)
fac[cnt++] = n/i;
fac[cnt++] = i;
}
}
sort(fac, fac+cnt);
for(LL i=1; i<=n; i++)
scanf("%lld",&a[i]);
mp2.clear();
mp1.clear();
LL cnt1 = 0;
for(LL i=0; i<cnt; i++){
mp2.clear();
for(LL j=1; j<=fac[i]; j++)
mp2[a[j]]++;
int ok = 0;
for(LL j=1+fac[i]; j<=n; j+=fac[i]){
mp1.clear();
for(LL k=j; k<j+fac[i]; k++){
mp1[a[k]]++;
if(mp1[a[k]] > mp2[a[k]]){
ok = 1;
goto endW;
}
}
}
if(!ok)
ans[cnt1++] = fac[i];
endW:;
}
for(LL i=0; i<cnt1; i++)
if(i != cnt1-1)
printf("%lld ",ans[i]);
else
printf("%lld\n",ans[i]);
}
return 0;
}