数论

Problem - B - Codeforces

题意

给定 \(n\;(1<=n<=3*10^5)\) 个数 \(a[i]\), \(1<=a[i]<=10^6\)

把 \(a[i]\) 看做是 n 个点的点权

如果 \(\frac {lcm(a[i],a[j])}{gcd(a[i],a[j])}\) 是完全平方数,则可以给 \(i\lrarr j\) 连一条无向边

每秒后都会令每个连通块中的每个点的点权变为整个连通块的点权乘积,有 \(q\;(1<=q<=3*10^5)\) 次询问,每次回答 \(w\) 秒后最大的连通块大小

思路

  1. \(\frac {lcm(a[i],a[j])}{gcd(a[i],a[j])}\) 是完全平方数 \(\Lrarr\) \(a[i]*a[j]\) 是完全平方数

  2. 设 \(a[i]=p_1^{s_1}*p_2^{s_2}*...p_n^{s_n}\), 我们不关心 \(s_i\) 具体是多少,只需要关心 \(s_i\) 的奇偶性,因此令 \(y=p_1^{s_1mod\;2}*p_2^{s_2mod 2}*...p_n^{s_nmod\;2}\)

  3. 初始时某个连通块有 3 种情况

    1. 每个点点权的 y 都为 1
    2. 每个点点权的 y 不为 1,连通块的大小是偶数
    3. 每个点点权的 y 不为 1,连通块的大小是奇数
  4. w = 0 时,求连通块大小的最大值即可;

    w >= 1 时,第 2 种连通块会转换为 1,第 3 种永远是第 3 种,因此把 2 转换成 1,再求 max(第 1 种的大小,第 3 种的大小的最大值)

  5. 实际上不需要建边跑并查集,复杂度太高;

    用 y 来表示即可,枚举 \(a[i]\), 分解 \(a[i]\) 求出对应的 y,\(mp[y]++\);

    \(mp[1]\) 就是第一种连通块的大小;其余的 y 也可用 \(mp[y]\mod2\) 来判断其大小的奇偶性,详细见代码

  6. 第 2 步的分解有两种方法:

    1. 线性筛 \(\sqrt{max(a[i])}\) 内的素数,用素数来分解,复杂度为线性筛的 \(O(1000)\), 分解单个数的 \(O(\frac {\sqrt {a[i]}}{\ln{\sqrt{a[i]}}})\)
    2. 线性筛 \(max(a[i])\) 内的素数,并在线性筛中预处理除 \(p[i]\) 表示 \(i\) 的最小质因子为 \(p[i]\);分解时每次就可以精准找到下一个要除的素数,复杂度为 线性筛的 \(O(10^6)\), 分解单个数的 \(O(\log {a[i]})\)

    当值域较小且要分解的数较多时用第 2 种更好

代码

#include <bits/stdc++.h>
using namespace std;
#define endl "\n" typedef long long ll;
typedef pair<int, int> PII; const int N = 3e5 + 10, M = 1e6 + 10;
int n;
int a[N];
int pr[M / 5], p[M], cnt;
void get_primes(int n)
{
p[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!p[i])
{
pr[++cnt] = i;
p[i] = i;
} for (int j = 1; j <= cnt && pr[j] <= n / i; j++)
{
p[i * pr[j]] = pr[j];
if (p[i] == pr[j])
break;
}
}
}
map<int, int> mp;
void fenjie(int x)
{
int y = 1;
while(x > 1)
{
int k = 0;
int minp = p[x];
while(x % minp == 0)
{
k++;
x /= minp;
}
if (k & 1)
y *= minp;
}
mp[y]++;
}
int main()
{
int T;
scanf("%d", &T);
get_primes(M - 10);
while(T--)
{
scanf("%d", &n);
mp.clear();
for (int i = 1; i <= n; i++)
{
int x;
scanf("%d", &x);
fenjie(x);
}
int ans0 = 0;
//w = 0
for (auto &[y, t] : mp)
ans0 = max(ans0, t);
//w >= 1
int ans1 = 0;
for (auto &[y, t] : mp)
{
//把第 2 种变成第 1 种
if (y != 1 && t % 2 == 0)
{
mp[1] += t;
mp[y] = 0;
}
}
for (auto &[y, t] : mp)
ans1 = max(ans1, t);
int q;
scanf("%d", &q);
while(q--)
{
int w;
scanf("%d", &w);
if (w >= 1)
printf("%d\n", ans1);
else
printf("%d\n", ans0);
}
}
return 0;
}

Codeforces Round #694 (Div. 1) - B. Strange Definition的更多相关文章

  1. Codeforces Round #425 (Div. 2) C - Strange Radiation

    地址:http://codeforces.com/contest/832/problem/C 题目: C. Strange Radiation time limit per test 3 second ...

  2. Codeforces Round #694 (Div. 2)

     A. Strange Partition 题意:就是求最小和最大的bi/x向上取整的和. 思路:见题解:https://blog.csdn.net/qq_45900709/article/detai ...

  3. Codeforces Round #697 (Div. 3) G. Strange Beauty (DP,数学)

    题意:给你一组数,问你最少删去多少数,使得剩下的数,每个数都能整除数组中其它某个数或被数组中其它某个数整除. 题解:我们直接枚举所有因子,\(dp[i]\)表示\(i\)在数组中所含的最大因子数(当我 ...

  4. Codeforces Round #373 (Div. 1)

    Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...

  5. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  6. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  7. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  8. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  9. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  10. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

随机推荐

  1. linux中磁盘如何由dos格式怎么变为gpt格式

    一般情况下,我们进行磁盘分区管理使用gdisk命令比较方便快捷,但假如我们想要大于2T的磁盘使用fdisk命令已经无法使用,此刻我们该怎么办?这时我们可以使用parted命令来把磁盘转换为gpt格式, ...

  2. Java面向对象之封装详解

    封装详解 封装 该露的露,该藏的藏 1.我们程序设计要追求"高内聚.低耦合".高内聚:类的内部数据操作细节自己完成,不允许外部干涉:低耦合:仅暴露少量的方法给外部使用. 封装(数据 ...

  3. 2021年爆出log4j漏洞修复

    (1)用户可自查系统是否引用 Apache log4j-core 依赖,没有引用则不受漏洞影响. (2)排查系统中日志配置是否采用远程动态加载模式.(3)排查系统中是否正在使用JDBCAppender ...

  4. C语言中关于宏定义的学习

    1.C语言中宏定义的使用 2.GCC官方文档 3.C语言宏定义的几个坑和特殊用法

  5. 浅谈spark

    spark spark是一个开源分布式计算框架,在于让计算更加快速,通常使用资源调度器yarn和spark自带的资源调度器standalond进行调度,spark相对于Hadoop更加快速,基于它是内 ...

  6. 蓝牙mesh组网实践(选择性配网与自配网参数分析)

    目录 使用配网器配网方式: 在之前的文章中介绍了CH582单片机在蓝牙mesh组网中的两种配网方式,有介绍到:未配网设备不能选择被哪个配网器配网,配网器可以选择给哪个未配网设备配网.接下来介绍在哪里可 ...

  7. 如何实现chrome谷歌浏览器多开(独立环境 独立cookie)、改任务栏图标

    多开谷歌浏览器: 由于各种各样的原因,你可能需要在一个电脑登录某个平台,比如一个电脑登录3个公众号,或者3个知乎等等. 最简单的方案是,直接安装3个不同的浏览器,比如一个谷歌浏览器,一个火狐浏览器,一 ...

  8. MSSQL执行超大.sql脚本

    1.打开mssql安装路径:找到Microsoft SQL Server Management Studio的图标,点击右键属性>打开文件位置 2.在安装路径下打开cmd控制台 3.输入命令: ...

  9. vmware15 nat模式下虚拟机能够ping通宿主机,宿主机无法平通虚拟机,nat网卡地址为192.168.0.1,网关为192.168.0.2.

    如图所示 最后网上教程看到,最后是修改nat网卡的巨型帧好的,废话不多数上图. 具体知道什么原因,开启这个就好了.

  10. firefox 利用 Selenium IDE 对 DBackup 进行自动化测试

    今天看<编写可维护的JavaScript>的时候有一章是专门讲 Selenium 对 JavaScript 进行自动化测试的. 在了解了 Selenium 的强大之后,动手试验了一下 fi ...