zoukankan      html  css  js  c++  java
  • Codeforces 980D Perfect Groups 计数

    原文链接https://www.cnblogs.com/zhouzhendong/p/9074164.html

    题目传送门 - Codeforces 980D

    题意

      $ m Codeforces$ 真是个令人伤心的地方。

      伤心的 $zzd$ 现在给你一个含有 $n$ 个数字元素的数列。

      $zzd$ 问你对于 $1$ 到 $n$ 之间的每一个 $k$ 满足 $Q(序列)=k$ 的原序列的连续子序列个数。

      其中,$Q()$定义如下:

      把当前数列中的数分组,使得同组中任意两个数的乘积为完全平方数。其中最小分组数就是 $Q()$ 的值。

      $nleq 5000,-10^8leq a_ileq 10^8$

    题解

      伤心的 $zzd$ 再一次来到了令人伤心的 $ m Codeforces $ ,再一次的看错题意,并再一次的没有考虑到坑点。

      很容易发现对于一个数,它的平方因子对最后的分组没有影响。

      我们把每一个数都除掉其最大平方因子,然后显然只有相同的数能分到同一组。

      于是离散化一下 $O(n^2)$ 统计即可。

      然后!!

      有一个特殊的数字叫做 "0" !

      $0$可以随便分组。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=10005;
    int n,a[N],cnt=0;
    int pcnt=0,prime[N],f[N];
    map <int,int> mp;
    int tot,v[N],ans[N];
    void get_prime(int n){
    	for (int i=1;i<=n;i++)
    		f[i]=1;
    	f[1]=0;
    	for (int i=2;i<=n;i++){
    		if (!f[i])
    			continue;
    		prime[++pcnt]=i*i;
    		for (int j=i*2;j<=n;j+=i)
    			f[j]=0;
    	}
    }
    int main(){
    	get_prime(10000);
    	scanf("%d",&n);
    	mp.clear();
    	for (int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		if (a[i]==0)
    			continue;
    		for (int j=1;j<=pcnt;j++)
    			while (a[i]%prime[j]==0)
    				a[i]/=prime[j];
    		if (mp[a[i]]==0)
    			mp[a[i]]=++cnt;
    		a[i]=mp[a[i]];
    	}
    	for (int i=1;i<=n;i++){
    		memset(v,0,sizeof v);
    		tot=0;
    		for (int j=i;j<=n;j++){
    			if (a[j])
    				tot+=v[a[j]]==0;
    			v[a[j]]++;
    			ans[max(tot,1)]++;
    		}
    	}
    	for (int i=1;i<=n;i++)
    		printf("%d ",ans[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    1869六度分离
    1162Eddy's picture
    hdu2544
    3549Flow Problem
    1272小希的迷宫
    2112HDU Today(Dijkstra)
    1878欧拉回路
    hdu1116Play on Words
    2112HDU Today(SPFA)
    在程序中动态创建视图
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/9074164.html
Copyright © 2011-2022 走看看