CodeForces 980 D Perfect Groups

Perfect Groups

题意:对于每一个连续的区间,区间内的数至少分成几个组,使得每个组内的数任意2个相乘是一个平方数。 输出的话是每个组数的个数。

题解:对于每一个数都将将他处理成不含平方数因子的数, 这样只有本身乘本身才会是一个平方数。

     然后对这个数组处理出这个数前面的位置, 然后 n^2跑出答案的时候, 开一个cnt记录数字出现的个数记录,每次扫到一个数的时候,只有这个数上次出现的位置在起点之前 才执行cnt++;

    注意的是 如果 该数是0那么也不执行cnt++; 因为0在这个题目中也算完全平数。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod = 1e9+7;
16 const int N = 1e4+10;
17 int vis[N], prim[N], cnt[N], pre[N], A[N];
18 int tot = 0, ans = 0;
19 map<int,int> mp;
20 void solve(int u){
21     for(int i = 0; i < tot; i++){
22         int t = prim[i] * prim[i];
23         if(abs(A[u]) < t) return;
24         while(A[u]%t == 0){
25             A[u] /= t;
26         }
27     }
28 }
29 int main(){
30     for(int i = 2; i < N; i++){
31         if(!vis[i]){
32             prim[tot++] = i;
33             for(int j = i; j < N; j += i)
34                 vis[j] = 1;
35         }
36     }
37     int n;
38     scanf("%d", &n);
39     for(int i = 1; i <= n; i++)
40         scanf("%d", &A[i]), solve(i);
41     for(int i=1; i<=n; i++) {
42         pre[i] = mp[A[i]];
43         mp[A[i]] = i;
44     }
45     for(int i=1; i<=n; i++) {
46         int cur=0;
47         for(int j=i; j<=n; j++) {
48             if(A[j] && pre[j] < i && A[j] != 0) cur++;
49             cnt[max(1,cur)]++;
50         }
51     }
52     for(int i = 1; i <= n; i++)
53         printf("%d%c", cnt[i], " \n"[i==n]);
54     return 0;
55 }
View Code

 

posted @ 2018-05-09 23:42  Schenker  阅读(269)  评论(0编辑  收藏  举报