题意:给一个序列,对于每一个连续的区间,区间内的数至少分成几个组,使得每个组内的数任意2个相乘是一个完全平方数(包括0)。 输出每个组数的个数。

$n \leq 5000 , |a_i| \leq 10^8$

我们发现,对于一个数$x$,我们把$x$所有成对的相同质因子除去之后得到的数是$f(x)$

那么分到同一个组的所有数的$f(x_i)$相同,0可以被分到任何集合

明显我们可以$n^2$做这道题,枚举一个子序列的右端点,然后从右到左枚举左端点,顺便维护最小组数。

对于加入一个数$x$,我们需要知道当前区间里面的数是否有和$x$相同的,如果有相同的,就加入那个集合,否则就新开一个集合

所以对于每一个点,我们预处理下一个和它相同的数的位置

当然0的情况不同,随便加到任意一个集合就可以了

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<set>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const int maxn=5000+7,M=120;
ll n,a[maxn],nxt[maxn],ans[maxn];
set<ll> prime;
set<ll>::iterator it; char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} ll qp(ll x,ll k,ll mod) {
ll rs=1;
while(k) {
if(k&1) rs=rs*x%mod;
k>>=1; x=x*x%mod;
}
return rs;
} ll gcd(ll x,ll y) {return y==0? x:gcd(y,x%y);} bool isprime(ll n) {
if(n==2||n==3||n==5||n==7) return 1;
if(n<2||(n%6!=1&&n%6!=5)) return 0;
ll m=n-1,t=0,x,y;
while((m&1)==0) t++,m>>=1;
For(qaq,1,20) {
x=rand()%(n-2)+2;
x=qp(x,m,n);
For(i,1,t) {
y=x*x%n;
if(y==1&&x!=1&&x!=n-1) return 0;
x=y;
}
if(x!=1) return 0;
}
return 1;
} ll prho(ll n,ll m) {
ll x=rand()%(n-1)+1,y=0;
for(ll i=1,k=1,d;y!=x;++i) {
if(i==k) {y=x;k<<=1;}
x=(x*x+m)%n;
d=gcd((y-x+n)%n,n);
if(d>1&&d<n) return d;
}
return n;
} void find(ll n,ll m) {
if(isprime(n)) {
it=prime.find(n);
if(it==prime.end()) prime.insert(n);
else prime.erase(it);
return;
}
ll p=n; while(p>=n) p=prho(n,m--);
find(p,M); find(n/p,M);
} ll get_num(ll n) {
// cerr<<"get_num("<<n<<")\n";
if(n==1||n==0) return n;
find(n,M);
ll rs=1;
while(!prime.empty()) {
it=prime.begin();
rs*=*it;
prime.erase(it);
}
return rs;
} int main() {
read(n); ll x;
For(i,1,n) {
// cerr<<"get a["<<i<<"]:";
read(x);
a[i]=get_num(abs(x));
if(x<0) a[i]=-a[i];
}
For(i,1,n) {
nxt[i]=n+1;
For(j,i+1,n) if(a[j]==a[i]) {nxt[i]=j;break;}
}
int now;
For(i,1,n) {
now=0;
Rep(j,i,1) {
if(a[j]&&nxt[j]>i) ++now;
++ans[now];
}
}
ans[1]+=ans[0];
For(i,1,n) printf("%lld ",ans[i]);
printf("\n");
return 0;
}

  

cf round480D Perfect Groups的更多相关文章

  1. CF 980D Perfect Groups(数论)

    CF 980D Perfect Groups(数论) 一个数组a的子序列划分仅当这样是合法的:每个划分中的任意两个数乘积是完全平方数.定义a的权值为a的最小子序列划分个数.现在给出一个数组b,问权值为 ...

  2. Codeforces 980 D. Perfect Groups

    \(>Codeforces\space980 D. Perfect Groups<\) 题目大意 : 设 \(F(S)\) 表示在集合\(S\)中把元素划分成若干组,使得每组内元素两两相乘 ...

  3. Codeforces980 D. Perfect Groups

    传送门:>Here< 题目大意:先抛出了一个问题——“已知一个序列,将此序列中的元素划分成几组(不需要连续)使得每一组中的任意两个数的乘积都是完全平方数.特殊的,一个数可以为一组.先要求最 ...

  4. Codeforces 980D Perfect Groups 计数

    原文链接https://www.cnblogs.com/zhouzhendong/p/9074164.html 题目传送门 - Codeforces 980D 题意 $\rm Codeforces$ ...

  5. codeforces 980D Perfect Groups

    题意: 有这样一个问题,给出一个数组,把里面的数字分组,使得每一个组里面的数两两相乘都是完全平方数. 问最少可以分成的组数k是多少. 现在一个人有一个数组,他想知道这个数组的连续子数组中,使得上面的问 ...

  6. Perfect Groups CodeForces - 980D

    链接 题目大意: 定义一个问题: 求集合$S$的最小划分数,使得每个划分内任意两个元素积均为完全平方数. 给定$n$元素序列$a$, 对$a$的所有子区间, 求出上述问题的结果, 最后要求输出所有结果 ...

  7. cf980d Perfect Groups

    题意 定义一个串的权值是将其划分成 \(k\) 组,使得每一组在满足"从组里选出一个数,再从组里选出一个数,它们的乘积没有平方因子"这样的前提时的最小的 \(k\).每组的数不必相 ...

  8. CF R 633 div 1 1338 C. Perfect Triples 打表找规律

    LINK:Perfect Triples 初看这道题 一脸懵逼.. 完全没有思路 最多就只是发现一点小规律 即. a<b<c. 且b的最大的二进制位一定严格大于a b的最大二进制位一定等于 ...

  9. cf Perfect Pair

    http://codeforces.com/contest/318/problem/C #include <cstdio> #include <cstring> #includ ...

随机推荐

  1. Android之selector选择器的使用

    1.selector简介 selector中文的意思选择器,在Android中常常用来作组件的背景,实现组件在不同状态下不同的背景颜色或图片的变换.使用十分方便.主要是用来改变ListView和But ...

  2. StringBuffer清空

    转载自:http://blog.sina.com.cn/s/blog_56fd58ab0100qfcz.html 在开发程序的时候,经常使用StringBuffer来进行字符串的拼接.如果在循环中来反 ...

  3. adb命令总结

  4. 图解nginx配置负载均衡

    1. 在Linux上准备两份tomcat 2. 修改两份tomcat的端口号 修改的端口如图所示: 3. 启动两个tomcat服务器 4. 修改两个服务器上的主页方便测试区分 5. 在nginx配置文 ...

  5. LUOGU P1903 [国家集训队]数颜色 / 维护队列

    传送门 解题思路 带修莫队,第一次写,其实和普通莫队差不多,就是多了个时间轴,块分n^(2/3)最优,时间复杂度O(n^(5/3)). #include<iostream> #includ ...

  6. 通过media媒体查询设置ie7/8样式、使用media判断各机型、手淘flexible.js

    @media all and (min-width:1280px){ /* 所有设备宽度大于1280干嘛干嘛嘞... */ body{ background:#f00; } } @media (min ...

  7. git简单使用命令

    每次都会忘记git使用命令 在本上做了笔记,网上也备份一份吧 这个是删除步骤: 拉取远程的Repo到本地(如果已经在本地,可以略过) $ git clone xxxxxx 在本地仓库删除文件  $ g ...

  8. 关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 转

    #!/usr/bin/python 是用来说明脚本语言是python的 是要用/usr/bin下面的程序(工具)python,这个解释器,来解释python脚本,来运行python脚本的. # -*- ...

  9. 每日上亿请求量的电商系统,JVM年轻代垃圾回收参数如何优化? ----实战教会你如何配置

    目录: 案例背景引入 特殊的电商大促场景 抗住大促的瞬时压力需要几台机器? 大促高峰期订单系统的内存使用模型估算 内存到底该如何分配? 新生代垃圾回收优化之一:Survivor空间够不够 新生代对象躲 ...

  10. Power Strings POJ2406 KMP 求最小循环节

    相比一般KMP,构建next数组需要多循环一次,因为next[j]代表前j-1个字符的最长相同前缀后缀,比如字符串为aab aab aab共9个字符,则next[10]等于前9个字符中最长相同前缀后缀 ...