互质数的个数(acwing)

news2024/11/28 3:49:08

题目描述:

给定 a,b,求 1≤x<a^b 中有多少个 x 与 a^b 互质。

由于答案可能很大,你只需要输出答案对 998244353 取模的结果。

输入格式:

输入一行包含两个整数分别表示 a,b,用一个空格分隔。

输出格式:

输出一行包含一个整数表示答案。

数据范围:

对于 30% 的评测用例,ab≤1e6;
对于 70% 的评测用例,a≤1e6,b≤1e9;
对于所有评测用例,1≤a≤1e9,1≤b≤1e18。

输入样例1:

2 5

输出样例1:

16

输入样例2:

12 7

输出样例2:

11943936

分析步骤:

  第一:我们看到这个题目,要求有多少个数互质。首先,就应该想到我们肯定是要用欧拉函数的解题目的其次,我们看到有a的b次方这种指数运算的话,就应该想到要运用快速幂的算法,特别是像这种题目数据量这么大的情况,一定一定是要用快速幂的。所以此题目分析到这里我们已经把题目的两大特点分析出来了:1.快速幂;2.欧拉函数。

  第二:回顾欧拉函数:

  • 我们先简单回顾一下什么是欧拉函数。

  • 欧拉函数的定义:1~n中与n互质的数的个数成为欧拉函数

  • 欧拉函数的性质:

  1. 如果p是质数的话,则与p互质的个数有:p-1个

  2. 如果p是质数的话,则与p^k互质的个数有:(p-1)*p^(k-1)

  3. 积性函数:若gcd(m,n) = 1也就是最大公约数为1时,则与(m*n)互质的个数有:与m的互质的个数乘上与n的互质的个数,就是(m*n)的答案。

  • 欧拉函数的计算公式:

  第三:书写主函数,构建整体框架:

  • 我们这道题目数据量巨大,所以我们最好定义a,b为long long类型

  • 如果底数 a == 1 的话那么无论b是多少答案都必定是0,这是一种剪枝的操作。

  • 进入我们欧拉函数的while循环

  • 我们运用试除法求因数,判断如果 x % i == 0 的话就代表 i 是 x 的因数,那么我们就把这个值给除干净;那么我们在让res乘上他的贡献。

  • while退出之后,在判断一下x是不是1,如果不是1的话就代表这个数也是一个因数,再让res乘上这个数的贡献。

  • 最后我们只需要把res的乘上快速幂的值那么我们的答案就出来了。

int main()
{
    LL a, b;
    cin >> a >> b;

    if (a == 1)
    {
        cout << 0 << endl;
        return 0;
    }

    LL res = a, x = a;
    for (int i = 2; i * i <= x; i ++ )
        if (x % i == 0)
        {
            while (x % i == 0) x /= i;
            res = res / i * (i - 1);
        }

    if (x > 1) res = res / x * (x - 1);

    cout << res * qmi(a, b - 1) % MOD << endl;
    return 0;
}

  第四:书写快速幂函数:

LL qmi(LL a, LL b)
{
    LL res = 1;
    while (b)
    {
        if (b & 1) res = res * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

----------

  第五:线性筛欧拉函数:

  • 我们线性筛欧拉函数,可以在O(logn)的时间复杂度之内完成筛法,大大降低了时间复杂度,比试除法更快更好

  • 线性筛欧拉函数也是借用线性筛模板,大同小异。

  • 首先我们定义st数组来判断我们这个数是不是质数定义primes数组储存质数定义mem数组储存我们之前算出的每一个数的答案。相当于记忆化搜索。

  • 将mem[1]初始化为1,因为1的质数只有1个。

  • 进入for循环,如果这个数状态没有被改过那么就证明这个数是质数,我们就把这个数放入质数数组,并且因为这个数是质数,那么这个数从1~i的与其互质的数为i-1。

  • 再进入一个for循环,我们要保证每一个合数一定是被他最小的质因子给筛去(这是线性筛的精髓)所以我们将i乘primes[j]赋给m,更改m的状态。因为m一定是两个数的乘积之和,那么他一定是合数所以要改变状态。

  • 再判断这个质因子是不是i的因子。如果是的话则代表了,i包含了m的所有质因子.例如:(12) = (2 * 6),因为2是质数,那么他就可以直接乘,6我们在之前的记忆化计算之中已经算出来了。所以可以写成 mem[m] = primes[j] * mem[i];

  • 如果不是的话,则代表i不能被primes[j]整除,则i与primes[j]互质,因为primes[j]一定是质数,所以他的互质数就等于primes[j] - 1,这是欧拉函数的性质,i的互质数就在我们之前记忆化搜索之中也计算出来了。将两个数相乘就可以得出答案。mem[m] = (primes[j]-1) * mem[i];

bool st[N];
int primes[N];
int mem[N];
void get_prime(int n ){
    mem[1] = 1;
    for(int i = 2 ; i <= n ; i ++){
        if(!st[i]) {
            primes[cnt++] = i;
            mem[i] = i-1;
        }
        for(int j = 0 ; i * primes[j] <= n ; j++){
            int m = i * primes[j];
            st[m] = true;
            if(i % primes[j] == 0) {
                mem[m] = primes[j] * mem[i];
                break;
            }else{
                mem[m] = (primes[j]-1) * mem[i];
            }
        }
    }
}

----------

大家可以好好看看如何用线性筛求解欧拉函数!!!这很重要,线性筛可以节约很多时间。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int MOD = 998244353;

LL qmi(LL a, LL b)
{
    LL res = 1;
    while (b)
    {
        if (b & 1) res = res * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

int main()
{
    LL a, b;
    cin >> a >> b;

    if (a == 1)
    {
        cout << 0 << endl;
        return 0;
    }

    LL res = a, x = a;
    for (int i = 2; i * i <= x; i ++ )
        if (x % i == 0)
        {
            while (x % i == 0) x /= i;
            res = res / i * (i - 1);
        }

    if (x > 1) res = res / x * (x - 1);

    cout << res * qmi(a, b - 1) % MOD << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1577919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

W25QXX系列W25Q64介绍

文章目录 前言介绍W25Q系列硬件电路四重SPI&#xff08;了解&#xff09; 框图Flash操作注意状态寄存器指令集电器特性 前言 W25Q64是一个8MByte大小的非易失性存储器&#xff0c;使用的是SPI协议&#xff0c;本文将全面介绍W25Q64的特性、工作原理以及注意事项 SPI详解见&am…

30万奖金谁能瓜分?OurBMC开源大赛决赛入围名单公示

首届开放原子开源大赛基础软件赛道自今年 1 月开启报名以来&#xff0c;吸引了全国各地 BMC 技术爱好者的广泛关注和踊跃报名。该赛事由开放原子开源基金会牵头&#xff0c; OurBMC 社区及理事长单位飞腾信息技术有限公司联合承办&#xff0c;以 “基于 BMC 技术的服务器故障诊…

CSS导读 (Emmet语法)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 续&#xff1a;七、Chrome调试工具 一、Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 &…

ctfshow web入门 php特性 web108--web115

web108 ereg函数相当于而preg_match()函数 ereg函数的漏洞&#xff1a;00截断。%00截断及遇到%00则默认为字符串的结束 strrev函数就是把字符串倒过来 就是说intval处理倒过来的传参c0x36d&#xff08;877&#xff09;?ca%00778 web109 异常处理类 通过异常处理类Excepti…

DFS-0与异或问题,有奖问答,飞机降落

代码和解析 #include<bits/stdc.h> using namespace std; int a[5][5]{{1,0,1,0,1}}; //记录图中圆圈内的值&#xff0c;并初始化第1行 int gate[11]; //记录10个逻辑门的一种排列 int ans; //答案 int logic(int x, int y, int op){…

3D引擎八叉树构建算法实现

最近&#xff0c;我一直在努力研究我的3D引擎Storm3D。 我花费大量时间的功能之一是开发一种通用且高效的八叉树数据结构&#xff0c;它将用于从碰撞检测到基于体素的渲染等多种用途。 在这里我将介绍构建八叉树的基本算法以及你可能遇到的一些障碍。 NSDT工具推荐&#xff1a;…

实习该选择c++后台开发(写业务逻辑)还是音视频开发(写sdk)?

后台开发:更多是理解需求、分析问题、解决bug等能力、对于逻辑培养有很大的帮助。可以进行软件开发、网络开发、游戏开发、以及之后可能的物联网相关开发。在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「音视频开发的资料从专业入门到高级教程」&#…

光伏电站投资与收益能成正比吗?

光伏电站作为绿色能源的代表&#xff0c;近年来在全球范围内得到了广泛的关注和应用。然而&#xff0c;光伏电站的投资与收益是否能成正比&#xff0c;始终是投资者和市场关注的焦点。本文将就此问题进行深入探讨。 首先&#xff0c;我们必须明确光伏电站的投资与收益并非简单的…

黑马Seata入门到实战教程(学习笔记)

Seata CAP理论 BASE理论 XA AT TCC sage模式 缺点&#xff1a;数据隔离性安全问题 四种模式对比

破晓数据新纪元:隐语隐私计算,携手共创安全智能的未来生态

1.业务背景&#xff1a;安全核对产生的土壤 隐语隐私计算在安全核对业务背景下的应用&#xff0c;主要聚焦于解决企业在数据交换和分析过程中面临的隐私保护问题。 在许多行业中&#xff0c;特别是在金融、医疗、政务等领域&#xff0c;数据的安全核对至关重要&#xff0c;例如…

数据结构系列-队列的结构和队列的实现

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 队列 队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO&#xff0c;…

Windows远程执行

Windows远程执行 前言 1、在办公环境中&#xff0c;利用系统本身的远程服务进行远程代码执行甚至内网穿透横向移动的安全事件是非常可怕的&#xff0c;因此系统本身的一些远程服务在没有必要的情况下建议关闭&#xff0c;防止意外发生&#xff1b; 2、作为安全人员&#xff0…

C++修炼之路之模板与STL简介

接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言&#xff1a; 在比如写一个交换函数时&#xff0c;由于交换数据的类型不同&#xff0c;可能要写出很多个交换函数&#xff0c;在c可以使用函数重载来实现&#xff0c;但如果数据类型…

一文了解重塑代币发行方式的创新平台 — ZAP

代币的发行方式对加密市场有着重要的影响&#xff0c;它直接影响着项目的社区建设、流动性、价格稳定性以及投资者的参与度&#xff0c;未来预期等&#xff01;合适的发行方式可以吸引更多的投资者和用户参与&#xff0c;提升项目的社区建设和价值实现。不当的发行方式和分配&a…

JSBridge原理 - 前端H5与客户端Native交互

1. 概述&#xff1a; 在混合应用开发中&#xff0c;一种常见且成熟的技术方案是将原生应用与 WebView 结合&#xff0c;使得复杂的业务逻辑可以通过网页技术实现。实现这种类型的混合应用时&#xff0c;就需要解决H5与Native之间的双向通信。JSBridge 是一种在混合应用中实现 …

字母大小写转换(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;char c1 A;char c2 0;//实现大小写转换&#xff1b;c2 c1 32;//输出结果&#xff1b;printf("c2的编码是&…

智慧农场物联网系统:重塑农业的未来

随着科技的进步&#xff0c;物联网技术正在逐渐改变我们的生活。在农业领域&#xff0c;物联网系统也正在发挥着越来越重要的作用&#xff0c;为智慧农场的发展提供了新的可能。本文将深入探讨智慧农场物联网系统的优势、应用场景、技术实现以及未来发展趋势。 一、智慧农场物…

2024年第七届信息管理与管理科学国际会议(IMMS 2024)即将召开!

2024年第七届信息管理与管理科学国际会议&#xff08;IMMS 2024&#xff09;将于2024年8月23-25日在中国北京举行。数字化时代&#xff0c;我们面临着诸多挑战&#xff0c;如信息安全问题、数据治理难题、管理创新需求等。IMMS 2024的召开&#xff0c;旨在让全球信息管理与管理…

express接口请求的几种方式分析总结

导语 在用express做接口开发的时候&#xff0c;我们要处理post,get,put,delete等请求&#xff0c;以及jsonp的方式&#xff0c;这篇文章记录下结合ajax&#xff0c;实现处理这些请求方式的过程 实现过程 上代码&#xff0c;主要演示post,get及jsonp的请求 <!DOCTYPE htm…

引脚数量最少的单片机

引脚数量最少的单片机 2款SOT23-6封装单片机介绍 参考价格 PMS150C-U06 整盘单价&#xff1a;0.19688&#xff0c;该芯片为中国台湾品牌PADAUK(应广) SQ013L-SOT23-6-TR 整盘单价&#xff1a;0.27876&#xff0c;该芯片为国产&#xff1a;holychip(芯圣电子) 上述价格为2024…