CF980D Perfect Groups

题目链接:http://codeforces.com/contest/980/problem/D

题目大意:

  对于 \(n\) 个数,考虑它的所有子串,每个个子串中的数字最少能分成 \(k\) 组,使得每一组中的所有数对之积都为完全平方数。对于每一个 \(k\) ,输出相应的子串数。

知识点:  算术基本定理

解题思路:

  对完全平方数进行质因数分解,不难发现它的所有质因数的指数都为偶数。因此两个数之积若为完全平方数,则这两者的所有质因子的指数之和必为偶数。对此,我们只需要考虑每个数的指数为奇数的质因子(若指数为偶数对于积的质因数的奇偶性没有影响),若两个数的指数为奇数的质因子相同,则二者相乘即得完全平方数。

AC代码:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn = 5000+5;
 5 
 6 int ans[maxn],a[maxn];
 7 
 8 int trans(int x){    //将 x 转化成由其指数为奇数的质因子相乘而得到的数
 9     if(x==0||x==1||x==-1)    return x;
10 
11     int ret=1;
12     if(x<0){
13         ret=-1;
14         x=-x;
15     }
16     for(int i=2;i*i<=x;i++){
17         if(x%i==0){
18             int has=0;
19             while(x%i==0){
20                 has++;
21                 x/=i;
22             }
23             if(has%2==1)
24                 ret*=i;
25         }
26     }
27     return ret*x;
28 }
29 
30 map<int,int>vis;
31 int ind[maxn];
32 bool used[maxn];
33 int main(){
34     int n;
35     scanf("%d",&n);
36     int cnt=0;
37     for(int i=1;i<=n;i++){
38         scanf("%d",&a[i]);
39         a[i]=trans(a[i]);
40 
41 //以下是一个 O(n*n) 的暴力
42         int t=vis[a[i]]; 
43         if(!t){
44             cnt++;
45             vis[a[i]]=cnt;
46             ind[i]=cnt;
47         }
48         else
49             ind[i]=t;
50     }
51 
52     for(int i=1;i<=n;i++){
53         memset(used,false,sizeof(used));
54         cnt=0;
55         for(int j=i;j<=n;j++){
56             if(a[j]==0){
57                 if(cnt==0)  ans[1]++;
58                 else    ans[cnt]++;
59             }
60             else{
61                 if(!used[ind[j]]){
62                     used[ind[j]]=true;
63                     cnt++;
64                 }
65                 ans[cnt]++;
66             }
67         }
68     }
69     for(int i=1;i<=n;i++){
70         if(i!=1)    printf(" ");
71         printf("%d",ans[i]);
72     }printf("\n");
73 
74     return 0;
75 }    

 

posted @ 2018-05-15 22:00  Blogggggg  阅读(192)  评论(0编辑  收藏  举报