hdu5908Abelian Period

来源:互联网 发布:电影截图拼图软件 编辑:程序博客网 时间:2024/05/29 18:13

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5908

题意:给定一个数组,求有多少个k使得数组能分成连续的k段使得每段中的每种数字的个数都是一样的。

分析:很容易想到每种数都分成k段那么原数组一定是被均分成k段,那么我们只需要判断每段中的每个数字是否都是一样的就行了,写点判断的标记就好了。

代码:

#include<map>#include<set>#include<stack>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef double db;typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const db eps=1e-5;const int N=1e5+10;const int M=1e5+10;const ll MOD=1000000007;const int mod=1000000007;const int MAX=1000000010;const double pi=acos(-1.0);int n,m,a[N],b[N],c[N],g[N],ans[N];int pd(int x) {    int i,j,d=n/x;    for (i=1;i<=n;i++)    if (g[a[i]]%x!=0) return 0;    for (i=1;i<=n;i++) b[i]=c[i]=0;    for (i=1;i<=x;i++) {        for (j=(i-1)*d+1;j<=i*d;j++) {            if (c[a[j]]%(g[a[j]]/x)==0) b[c[a[j]]/(g[a[j]]/x)]--;            c[a[j]]++;            if (c[a[j]]%(g[a[j]]/x)==0) b[c[a[j]]/(g[a[j]]/x)]++;        }        if (b[i]!=m) return 0;    }    return 1;}int main(){    int i,T;    scanf("%d", &T);    while (T--) {        scanf("%d", &n);        m=0;memset(g,0,sizeof(g));        for (i=1;i<=n;i++) scanf("%d", &a[i]),g[a[i]]++;        for (i=1;i<=n;i++)        if (g[i]) m++;        memset(ans,0,sizeof(ans));        for (i=1;i*i<=n;i++)        if (n%i==0) {            if (pd(i)) ans[n/i]=1;            if (pd(n/i)) ans[i]=1;        }        for (i=1;i<n;i++)        if (ans[i]) printf("%d ", i);        printf("%d\n", n);    }    return 0;}


0 0
原创粉丝点击