CodeForces 980 D 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 }