题目链接:点击查看

题目大意:给出 nnn 个数,要求选出最多的数,使得任意两个数的乘积不能是三次平方数,三次平方数,诸如23=8,33=272^3=8,3^3=2723=8,33=27

题目分析:这个模型和前两天 cfcfcf 上遇到的一个样:CodeForces - 1497E2

这个模型的特点就是,假设要使得任意两个数的乘积不能是 mmm 次平方数的话,当我们将所有的数字中,出现次数为 mmm 的倍数的质因子都筛掉后,剩下的数一定会两两匹配。具体到某个质因子来说,假设其出现次数为 xxx,那么其需要和出现次数为 m−xm-xm−x 的数字匹配,其乘积后该质因子的出现次数才能被 mmm 整除

下面就将本模型扩展到 mmm 次平方数来思考如何求解

又因为经过上述的处理后,除了 111 之外,其他的数都有且仅有唯一一个数字与其匹配。也就是对于每个数来说,只有一个数字与其乘积会不满足条件,所以这两个数字肯定不能同时出现。既然如此贪心去想的话,保留出现次数较多的那个数字显然是最优的

到此本题的思路就已经解决了,现在留下来两个难点需要我们逐个思考:

  1. 如何筛掉出现次数为 mmm 倍的质因子
  2. 在筛完的数字中,如何快速找到与其对应的那个数字,即满足两个数的乘积是 mmm 次平方数

针对第一点,最朴素的做法就是 O(n)O(\sqrt{n})O(n​) 的唯一分解定理了,对于出现次数可以被 mmm 整除的质因子直接舍弃即可,可惜时间复杂度不允许

然后考虑也比较常用的,预处理出每个数字的最小质因子,然后 O(logn)O(logn)O(logn) 去筛质因子,这种实现时间复杂度可行,但是我们无法预处理到 2e92e92e9 的数据范围

其实我们不难发现,并不需要枚举出所有的质因子然后判断,我们的目标是为了筛掉所有 mmm 次平方数的数字,换句话说我们可以预处理出 mmm 次平方的数字,然后用这些数字去筛即可,而这样的 mmm 次平方数,最多有 2e9m\sqrt[m]{2e9}m2e9​ 个数字,又因为合数总是可以被分解成质数,所以我们只需要保留质因子即可,这样有效数字最终约等于 2e9mlogm\frac{\sqrt[m]{2e9}}{logm}logmm2e9​​,针对本题而言,当 m=3m=3m=3 的时候,这个数值约等于 200200200

那么还剩下一个问题,如何找到对应的数字呢,实际上最朴素的做法还是 O(n)O(\sqrt{n})O(n​) 去唯一分解这个数,如果对于某个质因子 ppp,其出现次数是 xxx,那么其对应的那个数字, ppp 的出现次数一定是 m−xm-xm−x

到此为止,网上的部分题解,都是 O(nn)O(n\sqrt{n})O(nn​) 实现的,因为本题数据水了,所以给放过去了,其实一组很简单的 hackhackhack 样例就是, nnn 个 1e9+71e9+71e9+7,直接就把复杂度卡成至少 1e5∗1e4=1e91e5*1e4=1e91e5∗1e4=1e9 起步了

所以该如何去查找对应的那个数字呢,假设我们要找 xxx 对应的数字,只需要将 xxx 变成 xm−1x^{m-1}xm−1,然后再将出现次数为 mmm 的质因子筛掉即可,具体原理就是:对于任意两个相邻的自然数来说,都是互质的,所以 gcd(m−1,m)=1gcd(m-1,m)=1gcd(m−1,m)=1,对于公式 a+a∗(m−1)=a∗ma+a*(m-1)=a*ma+a∗(m−1)=a∗m,两边同时对 mmm 取模得到 a+a∗(m−1)=0∣ma+a*(m-1)=0|ma+a∗(m−1)=0∣m,所以将 xxx 变为 xm−1x^{m-1}xm−1 然后再将出现次数为 mmm 的倍数的质因子筛掉就可以找到对应的数字了

总的时间复杂度就是 O(n2e9m)O(n\sqrt[m]{2e9})O(nm2e9​),对于本题而言就是 O(200∗n)O(200*n)O(200∗n),实现的时候我套了个 mapmapmap ,理论上说应该是不可以的,但因为本题数据水,所以是可以过的,如果是正解的话我感觉需要打个哈希降一下复杂度,大概就是 unordered_map 了

代码:

// Problem: 牛牛的最大兴趣组
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/7604/C
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
bool vis[N];
vector<int>pri;
map<LL,int>mp;
void init() {for(int i=2;i<=2000;i++) {if(vis[i]) {continue;}for(int j=i+i;j<=2000;j+=i) {vis[j]=true;}}for(int i=2;1LL*i*i*i<=2e9;i++) {if(!vis[i]) {pri.push_back(i*i*i);}}
}
LL change(LL x) {for(auto it:pri) {while(x%it==0) {x/=it;}}return x;
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);init();int n;read(n);for(int i=1;i<=n;i++) {LL x;read(x);mp[change(x)]++;}int ans=0;for(auto &it:mp) {if(it.first==1) {ans++;continue;}LL rk=change(it.first*it.first);if(!mp.count(rk)) {ans+=it.second;} else {ans+=max(it.second,mp[rk]);it.second=mp[rk]=0;}}cout<<ans<<endl;return 0;
}

牛客 - 牛牛的最大兴趣组(思维+数论)相关推荐

  1. 牛客 - 牛牛的mex(主席树/思维)

    题目链接:点击查看 题目大意:给出一个长度为 n 的排列,再给出 m 次询问,每次询问需要回答区间 [ l , r ] 的 mex 题目分析:算是一道比较经典的题目了吧,先说一般做法,一般做法是 nl ...

  2. nowcoder 牛牛的最大兴趣组 质因子 + 思维

    传送门 文章目录 题意: 思路: 题意: 思路: 首先nnn很小的话可以暴力连边,让后染个色求一个颜色最多的即可.但是这个题显然不行,由于是三次方,所以考虑质因子入手. 首先很容易就能想到将所有的数的 ...

  3. 牛客题霸 [连续子数组的最大和] C++题解/答案

    牛客题霸 [连续子数组的最大和] C++题解/答案 题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和 ...

  4. 牛客IOI周赛26-提高组(逆序对,对序列,未曾设想的道路) 题解

    文章目录 逆序对 对序列 未曾设想的道路 牛客IOI周赛26-提高组 逆序对 这种套路之前已经见过几次了,肯定不是模拟操作数列 opt 1 对于i∈[1,l)⋃(r,n]i∈[1,l)\bigcup( ...

  5. 牛客IOI周赛27-普及组

    牛客IOI周赛27-普及组 A题(小H的小猫) (来源:nowcoder_牛客IOI周赛27-普及组_A题) 题目链接:https://ac.nowcoder.com/acm/contest/1915 ...

  6. 牛客IOI周赛22-提高组 华丽转身 C++

    牛客IOI周赛22-提高组 华丽转身 C++ 原题链接 在红星中学,一个年级一学年共有 n 场考试,每场考试都有 m 名同学参加,有一个巨佬叫李华 ,他已经不屑于通过AK考试来获得快感,于是他找到了一 ...

  7. 牛客竞赛语法入门班数组栈、队列和stl习题

    牛客竞赛语法入门班数组栈.队列和stl习题 L 指纹锁 set ,自带排序功能 可重写排序函数 cmp,注意外边写的要写成 operator()operator()operator(),结构体内部的排 ...

  8. 牛客 牛牛浇树(差分)

    文章目录 1. 题目 2. 解题 1. 题目 链接:https://ac.nowcoder.com/acm/contest/10323/A 来源:牛客网 牛牛现在在花园养了n棵树,按顺序从第1棵到第n ...

  9. 牛客 牛牛选物(01背包)

    文章目录 1. 题目 2. 解题 1. 题目 链接:https://ac.nowcoder.com/acm/contest/9887/A 来源:牛客网 牛牛有现在有n个物品,每个物品有一个体积v[i] ...

最新文章

  1. 计算机英语阅读路线,高考英语阅读理解真题解析·计算机运用
  2. 学习Java编程面向对象的五大基本原则
  3. C#数据结构-稀疏矩阵
  4. NMI watchdog: BUG: soft lockup - CPU#2 stuck for 23s!
  5. ionic2+angular2中踩的那些坑
  6. pycharm windows 打开命令行终端terminal
  7. 域还原的三种模式,以及应用场景
  8. GridView 中取值的方法汇总
  9. C#测绘兰勃特墨卡托投影
  10. 火狐浏览器扩展程序源代码的查看
  11. C#窗体标准计算器(上) 初级新手请多担待。
  12. RK系列SDK -- i2s mclk 无输出
  13. MD5加盐的一个简单算法
  14. Python爬取文章和小说内容
  15. python3 tkinter 随机答题
  16. IDEA去掉Performing Code Analysis,Check TODO
  17. find和findstr区别
  18. 如何成为学术论文写作高手(更新ing)
  19. 22.10.17 CF-1744D Divisibility by 2^n
  20. JavaScript中的表单编程

热门文章

  1. Nginx的Gzip和sendfile的共存问题
  2. 委派模式与策略模式综合应用
  3. 格式化输出字符串变量
  4. Zookeeper_原生API操作(一)
  5. java1121123211234321_使用for 语句打印显示下列数字形式:n=4 1 1 2 1 1 2 ,使用for 语句打印显示下列数字形式:n=4...
  6. python实现一个商品管理_python编写商品管理
  7. propertysource注解 找不到文件_WinXP系统电脑开机提示windows找不到null文件的解决方法...
  8. log4j2.xml 的标签 loggers 中 root 的属性 level 指的是什么
  9. STM32 地址偏移问题及怎么运用
  10. 前端js实现字符串/图片/excel文件下载