传送门

题目大意

给定$N$个数,求一个最大的子集,使得任意两两的乘积不是一个完全立方数。

$n\leq 10^5 A_i\leq 10^{10}$

题解

考虑两两乘积为$x^3$,由于$x^3\leq 10^{20}$,那么$x\leq 10^{\frac{20}{3}}$,那么$x$最多出现一个超过$10^{\frac{10}{3}}$的质因子,且这一质因子不会超过$10^{\frac{20}{3}}$。又由于$A_i\leq 10^{10}$,所以至多出现一个$> 10^5$的质因子,由于$x^3$由两个$A_i$相乘,那么$x$一定不会出现超过$>10^5$的质因子。

所以$x$由$[2,10^5]$内的质数幂构成,且$[10^{\frac{10}{3}},10^5]$内质数至多出现$1$个,且指数不超过$1$。

那么考虑筛出$10^5$以内的质数。

对于每一个$A_i$我们直接暴力枚举$<10^{\frac{10}{3}}$的质数(大约$300$个左右),直接筛掉,过滤掉质数是$3$的倍数的质因子,记录它由哪几个剩下的质因子构成,并将它每一个质因子质数模$3$的余数($1$或$2$)压进一个二进制状态中。对于剩下的数,如果它不为$1$,我们判断它是不是一个$<10^5$的质数或者一个$<10^5$的质数的平方,如果不是,那么它一定无法和别的任何一个数组成立方数,因为它肯定是一个$>10^5$的质数。否则,我们直接把这个稍大的质数当做之前过滤的数一样压入状态中。

对于两个过滤完的质因子的集合完全相同的数,它们能组成立方数当且仅当它们的二进制状态是恰好相反的,这样就能凑出每一个质因子的质数都是$3$的倍数。

然后就可以直接按照质因子集合放在一起,记录每一种状态和它的补集包含的数的数量,选集合大小更大的那一堆即可。

复杂度$O(n\log n+300n)$。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 300020
#define MAXN 100000
using namespace std;
int n,m,sz[M],K[M],res,mp[200002];
int od[M],ans; LL p[M],pri[M],t[M]; bool isp[M];
bool cmp(int x,int y){return t[x]<t[y];}
LL read(){
LL nm=0; char cw=getchar(); for(;!isdigit(cw);cw=getchar());
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0'); return nm;
}
int main(){
memset(isp,true,sizeof(isp));
for(int i=2;i<MAXN;i++){
if(!isp[i]) continue; pri[++m]=i;
for(int j=(i<<1);j<MAXN;j+=i) isp[j]=false;
}
n=read();
for(int j,i=1;i<=n;i++){
for(p[i]=read(),K[i]=sz[i]=0,j=t[i]=1;j<=308;j++){
if(p[i]%pri[j]) continue; int cnt=0;
while(!(p[i]%pri[j])) p[i]/=pri[j],++cnt; cnt%=3;
if(cnt) K[i]|=((cnt&1)<<sz[i]),sz[i]++,t[i]*=pri[j];
}
if(p[i]>1ll){
if(p[i]<MAXN) K[i]|=(1<<sz[i]),sz[i]++,t[i]*=p[i];
else {
LL qq=sqrt(p[i]);
if(qq*qq!=p[i]) ans++,i--,n--;
else sz[i]++,t[i]*=qq;
}
}
}
for(int i=1;i<=n;i++) od[i]=i; sort(od+1,od+n+1,cmp);
for(int l=1,r;l<=n;l=r+1){
for(r=l;r<n&&t[od[r]]==t[od[r+1]];r++);
if(t[od[l]]==1){ans++;continue;}
int maxn=(1<<sz[od[l]])-1;
for(int i=l;i<=r;i++) mp[K[od[i]]]++;
for(int i=l;i<=r;i++){
int x=K[od[i]],ot=(maxn^K[od[i]]);
if(mp[x]>=mp[ot]) ans+=mp[x],mp[x]=mp[ot]=0;
}
} printf("%d\n",ans); return 0;
}

Agc003_D AntiCube的更多相关文章

  1. AtCoder Grand Contest 003 D - Anticube

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_d 题目大意: 给定\(n\)个数\(s_i\),要求从中选出尽可能多的数,满足任意两个数之积 ...

  2. 【agc003D】Anticube

    Portal --> agc003D Description 给你\(n\)个数,要从里面选出最多的数满足这些选出来的数中任意两个数的乘积都不是立方数 Solution (为什么感觉最近这种解法 ...

  3. AT2004 Anticube

    https://www.zybuluo.com/ysner/note/1304774 题面 给定\(n\)个数\(s_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数. \(n\leq ...

  4. AtCoderAGC003D Anticube

    Description: 给定一个序列\(a\),要求选出最多的序列元素并保证两两元素的乘积不为立方数 Solution: 我们考虑哪些因子是有用的,如果一个因子的指数\(>3\),我们可以将他 ...

  5. Solution -「AGC 003D」「AT 2004」Anticube

    \(\mathcal{Description}\)   Link.   给定 \(n\) 个数 \(a_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数.   \(n\le10^5\) ...

  6. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  7. AtCoder Grand Contest 003

    AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...

  8. RE:从零开始的AGC被虐(到)生活(不能自理)

    RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...

  9. AtCoder Grand Contest

    一句话题解 QwQ主要是因为这篇文章写的有点长……有时候要找某一个题可能不是很好找,所以写了这个东西. 具体的题意.题解和代码可以再往下翻._(:з」∠)_ AGC 001 C:枚举中点/中边. D: ...

随机推荐

  1. linux的文件夹权限

    r:读取文件夹结构清单的权限,可以列出该文件夹下的所有文件. w:更改目录结构清单的能力,可以新建文件和目录,删除文件和目录(不管这个文件是否属于你),对文件和目录更名,移动文件和目录. x:具有x权 ...

  2. openCV图像形态学

    #include <cv.h> #include <highgui.h> #include <stdio.h> //平滑处理 int main() { IplIma ...

  3. 【python】-- 基于Django的杂货铺

    Django的杂货铺 此篇文章保存基于Django而实现的各种小功能示例 1.验证码 + Session 这个是在前端图片验证码的生成,再配合Session进行后端校验的功能示例 import ran ...

  4. "ORA-01012: not logged on"以及"Connected to an idle instance."解决思路

    今天测试用的ORACLE服务器出现卡顿情况,于是准备重启一下,在运行shutdown指令关闭数据库的时候意外断开连接,后面想再次进入ORACLE服务器启动时便遇见如下报错: 使用sqlplus /no ...

  5. Python锁

    # coding:utf-8 import threading import time def test_xc(): f = open("test.txt","a&quo ...

  6. linux 中解压与压缩 常用操作详细讲解

    平时有时候 会在服务器进行一些文件的操作,比如安装一些服务与软件等等,都有解压操作,一般在 导出一些简单的服务器文件,也是先压缩后再导出,因此,在这里根据平时用到解压与压缩命令的频率来记录下: 1.最 ...

  7. ABAP 内表

    定义内表 1. 先声明表结构, 再根据表结构定义内表.   TYPES: BEGIN OF w_itab, a(10), b(10), END OF w_itab. DATA: itab1 type ...

  8. Python日期和时间

    日期和时间主要有两个库,datetime和time. datetime: 日期:datetime.date.today() 日期和时间:datetime.datetime.now() 1000天之后: ...

  9. Microsoft Office Document Imaging批量ocr 方法

    先将pdf文件->导出->tiff文件,生成pdf每页的tiff文件 使用 G:\SoftWare-new\tiff文件合并拆分工具 将一个导出的单个tiff合并为一个tiff文件 再用 ...

  10. (转载)《C#高级编程》读书笔记

    C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) short System.Int16 16 ...