Abelian Period
Accepts: 288
Submissions: 984
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
设S是一个数字串,定义函数occ(S,x)表示S中数字x的出现次数。 例如:S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1。 如果对于任意的i,都有occ(u,i)=occ(w,i),那么我们认为数字串u和w匹配。 例如:(1,2,2,1,3)≈(1,3,2,1,2)。 对于一个数字串S和一个正整数k,如果S可以分成若干个长度为k的连续子串,且这些子串两两匹配,那么我们称k是串S的一个完全阿贝尔周期。 给定一个数字串S,请找出它所有的完全阿贝尔周期。
输入描述
输入的第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。 对于每组数据,第一行包含一个正整数n(n≤100000),表示数字串的长度。 第二行包含n个正整数S1,S2,S3,...,Sn(1≤Si≤n),表示这个数字串。
输出描述
对于每组数据,输出一行若干个整数,从小到大输出所有合法的k。
输入样例
2 6 5 4 4 4 5 4 8 6 5 6 5 6 5 5 6
输出样例
3 62 4 8
就根据题解写就行了,很明显我还太渣,没有写出来
#include<cstdio> #include<cstring> int num[100000+11],num_time[100000+11]; int ans[100000+11],n,total; int judge(int o) { int sum=0; int i,j,k; for(i=0;i<n/o;++i) { for(k=1;k<=o;++k) { ans[num[o*i+k]]++; if(ans[num[o*i+k]]*(n/o)>num_time[num[o*i+k]]*(i+1)) return 0; else if(ans[num[o*i+k]]*(n/o)==num_time[num[o*i+k]]*(i+1)) ++sum; } if(sum!=total) return 0; sum=0; } return 1; } int main() { int t; scanf("%d",&t); while(t--) { int i; scanf("%d",&n); memset(num_time,0,sizeof(num_time)); for(i=1;i<=n;++i) { scanf("%d",&num[i]); num_time[num[i]]++; } total=0; for(i=1;i<=100000;++i) if(num_time[i]) ++total; for(i=1;2*i<=n;++i) { if(n%i==0) { memset(ans,0,sizeof(ans)); if(judge(i)) { printf("%d ",i); } } } printf("%d\n",n); } return 0; }