整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


Codeforces Round #694 (Div. 2) D

很好的一道数论思维题

D - Strange Definition

Problem D Strange Definition

两个整数 xxx 和 yyy 是 相邻的 当 lcm(x,y)gcd(x,y)\cfrac{lcm(x,y)}{gcd(x,y)}gcd(x,y)lcm(x,y)​是完全平方数。

你有一个长度为 nnn 的序列 aaa。每一秒,所有的 aia_iai​都会变成序列中所有和它 相邻的 的数的乘积。令 did_idi​为数列中与 aia_iai​ 相邻的 的数的个数

有 qqq 次询问,每次询问给出一个 www,求在 www 秒时的 max⁡{di}\max\{d_i\}max{di​}

Solution

首先,我们来学习一个单词:perfectsquare\tt perfect\ squareperfect square:完全平方数…我还以为是完美的正方形,我说哪来的正方形…给我人看傻了…

以及 adjacent\tt adjacentadjacent: adj. 相邻的,毗邻的

然后开始照例分析题目中的性质。

首先是完全平方数,就是指整数 xxx 存在一个正整数 yyy ,使得 x=y2x=y^2x=y2,整数 xxx 就是一个完全平方数。

我们定义两个数是相邻的,是指两个整数 xxx 和 yyy ,满足: lcm(x,y)gcd(x,y)\cfrac{lcm(x,y)}{gcd(x,y)}gcd(x,y)lcm(x,y)​是完全平方数。

我们知道 gcd⁡(x,y)×lcm(x,y)=x×y\gcd(x,y) \times lcm(x,y)=x\times ygcd(x,y)×lcm(x,y)=x×y。

lcm(x,y)gcd(x,y)=x×ygcd⁡(x,y)2\cfrac{lcm(x,y)}{gcd(x,y)}=\cfrac{x\times y}{\gcd(x,y)^2}gcd(x,y)lcm(x,y)​=gcd(x,y)2x×y​

这个东西是完全平方数,也就意味着它可以被开根。

即 x×ygcd⁡(x,y)2=x×ygcd⁡(x,y)\sqrt{\cfrac{x\times y}{\gcd(x,y)^2}}=\cfrac{\sqrt{x\times y}}{\gcd(x,y)}gcd(x,y)2x×y​​=gcd(x,y)x×y​​

也就是说对于任意两个整数 xxx 和 yyy 而言,若 x×yx\times yx×y 是完全平方数,则这两个数是相邻的。

数论必备 唯一分解定理得:

x=p1α1×p2α2×⋯×pkαkx=p_1^{\alpha_1}\times p_2^{\alpha_2} \times \cdots\times p_{k}^{\alpha_{k}}x=p1α1​​×p2α2​​×⋯×pkαk​​

y=p1β1×p2β2×⋯×pkβky=p_1^{\beta_1}\times p_2^{\beta_2} \times \cdots\times p_{k}^{\beta_{k}}y=p1β1​​×p2β2​​×⋯×pkβk​​

x×y=p1α1+β1×p2α2+β2×⋯×pkαk+βkx\times y=p_1^{\alpha_1+\beta_1}\times p_2^{\alpha_2+\beta_2} \times \cdots\times p_{k}^{\alpha_k+\beta_{k}}x×y=p1α1​+β1​​×p2α2​+β2​​×⋯×pkαk​+βk​​

显然,若两个数的乘积是完全平方数,则所有质因子的次幂 α+β\alpha +\betaα+β 均为偶数。

也就意味着所有质因子对应的 α\alphaα 和 β\betaβ 是同奇偶性的,即 α\alphaα 是奇数, β\betaβ 也是奇数,或者 α\alphaα 是偶数, β\betaβ 也是偶数,或者一个是偶数,一个是 000 ,这样二者相加才是偶数。

因为我们发现还有 000 的存在,所以我们需要考虑如何把偶次幂与偶次幂,和 000 次幂与偶次幂表示成一个形式。很容易就想到了我们判断奇偶性的时候使用的 % 2,这样偶次幂或者本来就是 000 的最后都会变成 000 ,而奇次幂最后会变成 111 所以我们将每个数都质因数分解的同时,对于每一个质因子的次幂都 % 2 ,也就是质因数分解的时候指数一直 /= 2 也就是 /=i2/= i^2/=i2 。最后将 x=p1α1×p2α2×⋯×pkαkx=p_1^{\alpha_1}\times p_2^{\alpha_2} \times \cdots\times p_{k}^{\alpha_{k}}x=p1α1​​×p2α2​​×⋯×pkαk​​ 变为 x=p11×p20×⋯×pk0x=p_1^{1}\times p_2^{0} \times \cdots\times p_{k}^{0}x=p11​×p20​×⋯×pk0​ 的形式。

这样,最后只要是 000 就都是一组。

但是对于奇数而言,不一定。因为虽然都是是 111 ,但是奇次幂的话,必须能够配对,才是一组,配对的意思就是 变成 x=p11×p20×⋯×pk0x=p_1^{1}\times p_2^{0} \times \cdots\times p_{k}^{0}x=p11​×p20​×⋯×pk0​ 的形式以后,两个数剩余的质因子必须完全相同,也就是拥有相同的 111 次幂的质因子,也就是转换为上面的那个形式以后, 两个数的值完全相同。

我们可以使用 map 来储存同一组(相互都相邻)的元素个数。

分析完相邻的性质以后,我们知道如何判断是否相邻,我们可以直接对于每个输入的数,判断一下,存入 map 中。

然后再来考虑第二个问题,题目中的操作,合并。

我们从第 000 秒开始,每一秒,每一个数都会变成所有与自己相邻(包括自己)的数的乘积,然后有 qqq 次询问,每次会问第 ω\omegaω 秒,数列中,所有相邻组(全部两两相邻)中元素个数最多的个数。ω≤1018\omega \le10^{18}ω≤1018。所以我们瞬间就可以看出点什么东西,就是这个操作修改以后,答案肯定存在一个循环节或者之后的某一时刻就不会再发生变化了。因为询问的数据太大, 啥数据结构都不可能存得下,也不可能快速地求解。

然后我们来分析这个操作,同一组的所有的数都会同时合并,我们根据上面的分析,知道一共有四种组别

  1. 个数为偶数的 000 组(偶次幂)
  2. 个数为奇数的 000 组(偶次幂)
  3. 个数为偶数的 111 组(奇次幂)
  4. 个数为奇数的 111 组(奇次幂)

我们来分析这四种组别合并后会发生什么。

  • 第一种,第二种

我们的合并操作是全部数的乘积,对于质因数分解后的 xxx ,全部数的乘积实际上就是所有数的指数的和,而第一种,第二种,不管组内个数是奇数个还是偶数个,因为都是偶数,所以和仍然是偶数,也意味着还是第一种或者第二种,而第一种和第二种实际上是同一种,因为都是相邻的,这里分开只是两种不同的情况。所以第一第二种任意秒以后,仍然还是第一第二种。

  • 第三种

偶数个全部对应的奇次幂,和为偶数,因为每个次幂都是奇数,也就是 111 ,奇数加奇数为偶数,在第一秒第一次合并以后归为第一种或者第二种。

  • 第四种

奇次幂,还是奇数个,那么相乘,也就是指数相加,永远都还是第四种。

分析完我们发现,询问一共分 ω=0\omega=0ω=0 和 ω>0\omega>0ω>0 两种情况, ω=0\omega=0ω=0 的时候,数列中的数一共分为三种

  • 第一种就是我们上面说的第一第二种,我们累计所有指数是偶次幂的元素的个数。
  • 第二种为我们上面说的第三种,即虽然是 111 组,但是个数是偶数,也就是我们 map 存的第二维是偶数。
  • 第三种就是我们上面说的第四种,奇数个的奇数次幂,我们用 map 来hash一下,对于这一种的每一个值,都分为每一组,取最值。

ω=0\omega=0ω=0 时答案就是上述三种的元素个数的最大值。

ω>0\omega>0ω>0 时, 第二种全部归为第一种,所以我们只需要用第三种里最大的那一组的个数,与第一种元素个数加上第二种的元素个数,取最大值即可。

detail

虽然上面说了那么大一堆,这些实际上只是我当时做题的时候的心理活动,在演草纸上画思维导图来分类讨论,总共花了不到 101010 分钟,因为写题解我习惯讲的比较详细,我希望可以把如何思考问题带给大家,所以内容有点多了,请大家见谅 …

Code

实现就非常简单了,照着上面的思路模拟一遍就行了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>using namespace std;
const int N = 3e5 + 7, mod = 1e9 + 7;
typedef long long ll;
unordered_map<int, int> Hash;
void get_factor(int x)
{for(int i = 2; ; ++ i) {int even = i * i;while(x % even == 0 && x >= even) x /= even;if(x < even) break;}Hash[x] ++ ;我们实际上只需要知道它是奇还是偶//x就是把所有的质因子的次方全部压成0或者1,0就是偶次幂,x=1(被除尽了),1次就是奇次幂。x=若干一次质因子的乘积//偶次幂无所谓,奇次幂必须所含奇次幂的质因子全部完全相同才是一组(能凑成偶数,也就是完全平方数)
}
int n, m, t, q;
int main()
{scanf("%d", &t);while(t -- ) {Hash.clear();scanf("%d", &n);for(int i = 1; i <= n; ++ i) {int a;scanf("%d", &a);get_factor(a);}int ans1 = 0, ans2 = 0;for(auto it = Hash.begin(); it != Hash.end(); ++ it) {//0秒的情况不变ans1 = max(ans1, it -> second);//second是个数,0秒没有变化的时候,最大数量的那组就是最大的那组//1秒的情况合并if(it -> second % 2 == 0 || it -> first == 1)//(组内有偶数个 || 这个组是偶数次幂组)ans2 += it->second;//1秒钟后就会全部归为偶组}ans2 = max(ans2, ans1);//取奇数组和偶数组中的最大值scanf("%d", &q);for(int i = 1; i <= q; ++ i) {ll w;scanf("%lld", &w);if(w == 0)printf("%d\n", ans1);else printf("%d\n", ans2);}}return 0;
}

CF1471 D - Strange Definition(思维,分类讨论,lcm,gcd的性质,数论)相关推荐

  1. 分类讨论 ---- 2020 icpc 上海 Walker (二分 or 思维分类讨论)

    题目链接 题目大意: 就是两个人在坐标轴上面,有起始的坐标p1,p2p1,p2p1,p2,和速度v1,v2v1,v2v1,v2,问你访问完这长度为nnn的数轴最短时间是多少? 解题思路: 大佬有直接二 ...

  2. codeforces1471 D. Strange Definition

    D. Strange Definition 大佬题解 由lcm(x,y)=xygcd(x,y)lcm(x,y)=\frac{xy}{gcd(x,y)}lcm(x,y)=gcd(x,y)xy​可知,如果 ...

  3. P7108 移花接木(分类讨论思维)

    P7108 移花接木(分类讨论&思维) 题意 给定一棵无限高度的满 a a a叉树. 给定两个操作. 1.删除一个结点及其子树. 2.将一个结点及其子树移到另一个结点. 求将满 a a a叉树 ...

  4. Unfair contest 模拟-分类讨论

    题意 : 两人比赛,n个裁判,给分范围[1,h][1, h][1,h],去掉s个最高分和t个最低分,给出n - 1个裁判的给分,第n个裁判想让第1个人赢,并且最小化给1的分数a[n]a[n]a[n] ...

  5. 2020ICPC(上海) - Walker(分类讨论+二分)

    题目链接:点击查看 题目大意:在长度为 n 的数轴上给出两个人的初始位置和速度,问使得每个位置至少被一个人走过的时间是多少 题目分析:分类讨论题目,分四种情况讨论即可,设 p1 < p2: p1 ...

  6. 【UOJ#33】【UR #2】树上GCD(长链剖分/根号分类讨论)

    [UOJ#33][UR #2]树上GCD 求解树上两个点到lca的距离的最大公约数是k的对数 首先我们很容易就想到莫比乌斯反演,那么利用倍数形式,我们只需要求解是i的倍数的对数. 考虑枚举lca,这个 ...

  7. uoj#246. 【UER #7】套路(dp+分块?分类讨论?)

    题目链接 分析: 目前为止我只能理解dp部分 我就喜欢这种单纯不做作的题目 一看名字就明白了这道题的本质 中二的题目描述 很显然,我们的关键就是求出最小相似度 朴素算法n^4 如果我们现在有一个权值数 ...

  8. Vasya and Multisets CodeForces - 1051C 模拟|分类讨论

    题意:把数组分成两个集合 每个集合中元素数量为1的个数相同(此个数可以是0) 分析: 这类问题就是要各种可能情况考虑到     然后分类讨论     完整地正确分类就AC     否则gg 如果数量为 ...

  9. P3842 [TJOI2007]线段(线性dp,分类讨论)

    P3842 [TJOI2007]线段 题意 [TJOI2007]线段 题目描述 在一个 n×nn \times nn×n 的平面上,在每一行中有一条线段,第 iii 行的线段的左端点是(i,Li)(i ...

最新文章

  1. GNN教程:第六篇Spectral算法细节详解!
  2. DeepMind提出基于视觉的强化学习模型,十八般兵器对机器人不在话下
  3. 用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联。
  4. 浏览器中关于事件的那点事儿
  5. html嵌入war_WAR文件与具有嵌入式服务器的Java应用程序
  6. linux-Centos7安装nginx
  7. 制作一个大风车加载条
  8. JVM007_运行时栈帧结构
  9. 树形结构 —— 并查集 —— 基本操作
  10. const成员函数重载
  11. spool命令、创建一个表,创建而且copy表,查看别的用户下的表,rowid行地址 索引的时候使用,表的增删改查,删除表,oracle的回收站...
  12. ubuntu18重启vncserver_Ubuntu 18.04 LTS安装vncserver虚拟网络控制台
  13. HTML5期末大作业:影视视频网站设计——爱影评在线电影(10页面) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码
  14. 【C语言】球从100米自由落下,每次落地后反跳回原高度的一半。当10次落地时,共经过多少米,第10次反弹多高。
  15. C# dotnet 获取某个字符所在 Unicode 字符平面映射
  16. 字体 跨域访问_21个访问量最大的免费字体网站
  17. Axure制作菜单栏效果
  18. Python 用户输入和循环的学习
  19. linux怎么查看是不是centos版本
  20. HashMap源码阅读笔记

热门文章

  1. 基于OpenCV的数字识别系统
  2. python04-列表与元祖
  3. 布局AR VR领域?Tessera 8.5亿美元收购音频公司DTS
  4. ORACLE的DUAL表及DB2的SYSIBM.SYSDUMMY1
  5. [转]PDO防注入原理分析以及使用PDO的注意事项
  6. Socket程序从windows移植到linux下需要注意的
  7. Word遇到问题需要关闭
  8. [收集] Web服务相关的, 介绍框架(framework)类的论文
  9. Mysql 基本命令
  10. linux sersync2 ssh start=true,rsync+nfs+sersync实战案例