鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5908
題意:
設SSS是一個數字串,定義函數occ(S,x)occ(S,x)occ(S,x)表示SSS中數字xxx的出現次數。 例如:S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1S=(1,2,2,1,3),occ(S,1)=2,occ(S,2)=2,occ(S,3)=1。 如果對於任意的iii,都有occ(u,i)=occ(w,i)occ(u,i)=occ(w,i)occ(u,i)=occ(w,i),那麼我們認爲數字串uuu和www匹配。 例如:(1,2,2,1,3)≈(1,3,2,1,2)。 對於一個數字串SSS和一個正整數kkk,如果SSS可以分成若干個長度爲kkk的連續子串,且這些子串兩兩匹配,那麼我們稱kkk是串SSS的一個完全阿貝爾週期。 給定一個數字串SSS,請找出它所有的完全阿貝爾週期。
題解:
直接用map暴力
CODE:
#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug"<<endl
const int MAXN = 100007;
const int MAXM = 20007;
const int MOD = 1e9 + 9;
using namespace std;
int ans[MAXN],all;
int a[MAXN],p[MAXN];
int n;
bool judge(int len)
{
map<int, int>cnt1, cnt2;
for(int i=0; i<len; ++i)
cnt1[ a[i] ]++;
for(int i=len; i<n; ++i)
{
if(i%len==0&&i>len)if(cnt1!=cnt2)return 0;
if(i%len==0)cnt2.clear();
cnt2[ a[i] ]++;
}
if(cnt1!=cnt2)return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<n; ++i)
scanf("%d",&a[i]);
int temp=0;
for(int i=1; i*i<=n; ++i)
if(n%i==0)
{
p[temp++]=i;
if(i*i!=n)p[temp++]=n/i;
}
sort(p,p+temp);
temp--;
all=0;
int all=0,k=0;
for(int i=0; i<temp; ++i)
{
k=0;
for(int j=0; j<all; ++j)
if(p[i]%ans[j]==0)
{
k=1;
ans[all++]=p[i];
break;
}
if(!k)
{
if(judge(p[i]))
ans[all++]=p[i];
}
}
for(int i=0; i<all; ++i)
printf("%d ",ans[i]);
cout<<p[temp]<<endl;
}
return 0;
}
/*
2
6
5 4 4 4 5 4
8
6 5 6 5 6 5 5 6
*/