zoukankan      html  css  js  c++  java
  • 【CF980D】Perfect Groups(仔细一想是道水题)

    点此看题面

    • 给定一个长度为(n)的序列。
    • 定义一个序列的值为最少要划分多少组,使得每组的数两两乘积都是平方数。
    • 现在要对于每个(kin[1,n]),求出这个序列有多少值为(k)的子串。
    • (nle5000)

    解题思路

    重要的事情放前面:注意特殊处理(0)的情况,因为(0)可以贴到任意一组里面!

    然后考虑不为(0)的情况,我们先去掉(a_i)的全部平方因子,然后就发现两数乘积为平方数只可能是这两数相同。

    也就是只有相同的数才能并到一组,而既然要求最小组数,则相同的数必然并到一组,因此只要求有多少不同的数即可。

    直接暴枚所有子串就做完了。

    代码:(O(n^2))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 5000
    using namespace std;
    int n,a[N+5],dc,dv[N+5],s[N+5],vis[N+5];
    int main()
    {
    	RI i,j;for(scanf("%d",&n),i=1;i<=n;dv[i]=a[i],++i)
    		for(scanf("%d",a+i),j=2;j*j<=abs(a[i]);++j) W(!(a[i]%(j*j))) a[i]/=j*j;//除去所有平方因子
    	sort(dv+1,dv+n+1),dc=unique(dv+1,dv+n+1)-dv-1;//排序去重
    	for(i=1;i<=n;++i) a[i]=lower_bound(dv+1,dv+dc+1,a[i])-dv;//离散化
    	RI t;for(i=1;i<=n;++i) for(t=0,j=i;j<=n;++j)//暴枚子串
    		dv[a[j]]&&vis[a[j]]^i&&(vis[a[j]]=i,++t),++s[max(t,1)];//统计有多少不同的数(0除外),但注意全是0也得有一组
    	for(i=1;i<=n;++i) printf("%d%c",s[i]," 
    "[i==n]);return 0;//输出答案
    }
    
  • 相关阅读:
    Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. ......
    UVA 1597 Searching the Web
    UVA 1596 Bug Hunt
    UVA 230 Borrowers
    UVA 221 Urban Elevations
    UVA 814 The Letter Carrier's Rounds
    UVA 207 PGA Tour Prize Money
    UVA 1592 Database
    UVA 540 Team Queue
    UVA 12096 The SetStack Computer
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF980D.html
Copyright © 2011-2022 走看看