【CCPC】CCPC 2023 Shenzhen Site I

news2024/10/11 5:23:23

Indeterminate Equation

#质因子分解 #数学 #二分 #分治

题目描述

Given positive integers n, k, find the number of positive integer solutions to the indeterminate equation a k − b k = n a^k − b^k = n akbk=n

输入格式

The first line of input is an integer T ( 1 ≤ T ≤ 20 ) (1 ≤ T ≤ 20) (1T20) indicating the number of queries. The following T lines,
each contain two integers n, k indicating a single query. It is guaranteed that 1 ≤ n ≤ 1 0 18 1 ≤ n ≤ 10^{18} 1n1018, 3 ≤ k ≤ 64 3 ≤ k ≤ 64 3k64.

输出格式

For each query, output a single line contains a single integer, indicating the answer

样例 #1

样例输入 #1

3
7 3
15 4
31 5

样例输出 #1

1
1
1

解法

解题思路

首先对于 a k − b k a^k - b^k akbk,我能够提出一个 ( a − b ) (a-b) (ab),例如当 k = 3 k=3 k=3时,我们可以得到
a 3 − b 3 = ( a − b ) ( a 2 + a b + b 2 ) a^3-b^3 = (a-b)(a^2+ab+b^2) a3b3=(ab)(a2+ab+b2)

由于 n ≤ 1 e 18 n\leq 1e18 n1e18,所以我们可以通过大数质因子 p o l l a r d − r h o pollard-rho pollardrho分解出所有 n n n的质因子,然后跑 d f s dfs dfs搜索出所有的因子,因为在 1 e 18 1e18 1e18以内,因子个数不超过 1 e 5 1e5 1e5个。

那么我们就可以枚举 n n n的因子作为 a − b a-b ab的值,二分出满足条件的 b b b即可。

注意 a k − b k a^k -b^k akbk极有可能爆 _ _ i n t 128 \_\_int128 __int128,因此我们需要提前找出一个 a k − b k ≤ n a^k - b^k \leq n akbkn的上界。

由于当 k = 3 k=3 k=3时,上界可以到达接近 5 e 8 5e8 5e8,我们特判一下这个情况即可。

代码

using pii = std::pair<int, int>;

const int N = 2e5 + 10;

int mul(int a, int b, int m)
{
    int r = a * b - m * (int)(1.L / m * a * b);
    return r - m * (r >= m) + m * (r < 0);
}
int mypow(int a, int b, int m)
{
    int res = 1 % m;
    for (; b; b >>= 1, a = mul(a, a, m))
    {
        if (b & 1)
        {
            res = mul(res, a, m);
        }
    }
    return res;
}
int B[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
int ctz(unsigned int n) {
    if (n == 0) return 32; // 处理边界情况
    int count = 0;
    while ((n & 1) == 0) {
        n >>= 1;
        count++;
    }
    return count;
}

bool MR(int n)
{
    if (n <= 1)
        return 0;
    for (int p : B)
    {
        if (n == p)
            return 1;
        if (n % p == 0)
            return 0;
    }
    int m = (n - 1) >> ctz(n - 1);
    for (int p : B)
    {
        int t = m, a = mypow(p, m, n);
        while (t != n - 1 && a != 1 && a != n - 1)
        {
            a = mul(a, a, n);
            t *= 2;
        }
        if (a != n - 1 && t % 2 == 0)
            return 0;
    }
    return 1;
}

int PR(int n)
{
    for (int p : B)
    {
        if (n % p == 0)
            return p;
    }
    auto f = [&](int x) -> int
        { x = mul(x, x, n) + 1; return x >= n ? x - n : x; };
    int x = 0, y = 0, tot = 0, p = 1, q, g;
    for (int i = 0; (i & 255) || (g = std::gcd(p, n)) == 1; i++, x = f(x), y = f(f(y)))
    {
        if (x == y)
        {
            x = tot++;
            y = f(x);
        }
        q = mul(p, std::abs(x - y), n);
        if (q)
            p = q;
    }
    return g;
}

std::vector<int> fac(int n) {
#define pb emplace_back
    if (n == 1)
        return {};
    if (MR(n))
        return { n };
    int d = PR(n);
    auto v1 = fac(d), v2 = fac(n / d);
    auto i1 = v1.begin(), i2 = v2.begin();
    std::vector<int> ans;
    while (i1 != v1.end() || i2 != v2.end())
    {
        if (i1 == v1.end())
        {
            ans.pb(*i2++);
        }
        else if (i2 == v2.end())
        {
            ans.pb(*i1++);
        }
        else
        {
            if (*i1 < *i2)
            {
                ans.pb(*i1++);
            }
            else
            {
                ans.pb(*i2++);
            }
        }
    }
    return ans;
}

__int128_t quick(__int128_t x, int n)
{
    __int128_t res = 1;
    while (n)
    {
        if (n & 1)
            res = (res * x);
        x = x * x;
        n >>= 1;
    }
    return res;
}

std::ostream& operator<<(std::ostream& os, __int128_t n) {
    std::string s;
    while (n) {
        s = s + std::to_string((int)n % 10);
        n /= 10;
    }
    std::reverse(s.begin(), s.end());
    return os << s;
}

std::vector<int> getfac(int n) {
    std::vector<int> pos = fac(n);

    std::map<int, int> cnt;
    for (auto i : pos) cnt[i]++;
    std::vector<pii> tmp;
    for (auto& [x, y] : cnt) tmp.push_back({ x, y });
    int len = tmp.size();
    std::set<int> st;
    auto dfs = [&](auto&& self, int mul, int dep) ->void {
        if (n % mul == 0)
            st.insert(mul);
        if (dep == len)
            return;
        int p = 1;
        for (int i = 0; i <= tmp[dep].second; i++) {
            if (i != 0)
                p *= tmp[dep].first;
            self(self, mul * p, dep + 1);
        }
        };
    dfs(dfs, 1, 0);

    std::vector<int>res;
    for (auto& x : st) res.emplace_back(x);
    return  res;
}

void solve()
{
    int n, k;
    std::cin >> n >> k;
   
    int limit = 0,res = 0;

    if (k == 3) {
        limit = 5e8;
    }

    for (int i = 1; i <= 1e6; i++) {
        if (quick(i, k) - quick(i - 1, k) > n) {
            limit = i;
            break;
        }
    }

    auto factor = getfac(n);

    for (auto x : factor) {
        int l = 1, r = limit ,ans = 0;
        while (l <= r) {
            int mid = l + r >> 1;
            __int128_t a = mid + x, b = mid;
            
            int ok = 0;
            a = quick(a, k), b = quick(b, k);
            if (a - b == n) {
                ans = mid;
                break;
            }
            else if (a - b > n) r = mid - 1;
            
            else l = mid + 1;
        }
        res += ans;
        
    }
    std::cout << res << "\n";

}

signed main() {
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);

    int t = 1;
    std::cin >> t;

    while (t--) {
        solve();
    }
};

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

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

相关文章

云栖实录 | 大模型驱动,开源融合的 AI 搜索产品发布

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 郭瑞杰 | 阿里云智能集团资深技术专家&#xff0c;阿里云 AI 搜索负责人 邹 宽&#xff5c;阿里云智能集团高级产品专家&#xff0c;阿里云 AI 搜索产品负责人 活动&#xff1a;…

【CSS Tricks】鼠标滚轮驱动css动画播放,使用js还是css?

目录 引言一、js实现1. 实现思路2. 实现案例3. 看下效果 二、css实现1. 代码修改2. 属性介绍2.1 看下浏览器支持性2.2 常用属性值2.2.1 scroll&#xff08;&#xff09;2.2.2 view&#xff08;&#xff09; 三、总结 引言 本篇为css的一个小技巧 页面中的动画效果随着滚轮的转动…

Unity 从零开始的框架搭建1-2 事件的发布-订阅-取消的小优化及调用对象方法总结[半干货]

该文章专栏是向QFrameWork作者凉鞋老师学习总结得来&#xff0c;吃水不忘打井人&#xff0c;不胜感激 Unity 从零开始的框架搭建1-1 unity中对象调用的三种方式的优缺点分析【干货】-CSDN博客 原来 其实就是对上一节的事件发布订阅类的小优化&#xff0c;原来是这样子的 p…

达梦DBLINK访问ORACLE配置方法

目录 1、概述 2、测试环境 3、语法简介 4、配置访问DM的DBLINK 5、配置访问ORACLE的DBLINK 5.1 通过OCI配置 5.2 通过ODBC配置 1、概述 本文介绍了达梦DBLINK的配置方法。有3部分内容&#xff0c;1&#xff09;达梦访问到达梦的配置方法&#xff1b;2&#xff09;通过OC…

视频切分成指定大小片段

某些时候&#xff0c;由于上传限制&#xff0c;我们可能想把视频切分成尽量少且满足大小限制的片段&#xff0c;不改变视频原先的格式 实现思路&#xff1a;得到视频的总时长&#xff0c;总文件大小&#xff0c;根据大小限制&#xff0c;确定分割片段个数&#xff0c; 得到每段…

rpa批量发送邮件如何通过编辑器编发邮件?

rpa批量发送邮件的技巧&#xff1f;怎么使用rpa邮箱群发助手&#xff1f; 手动发送邮件变得越来越繁琐且效率低下。为了解决这一问题&#xff0c;越来越多的企业开始采用RPA技术来批量发送邮件。AokSend将详细探讨如何通过编辑器来实现rpa批量发送邮件的功能&#xff0c;从而提…

75.【C语言】文件操作(3)

目录 6.文件的顺序读写 1.几个顺序读写函数 1.fgetc函数 代码示例 代码改进 2.fputc函数 3.fputs函数 如果需要换行,应该写入换行符(\n) 4.fgets函数 1.读取单行字符串 2.读取多行字符串 6.文件的顺序读写 1.几个顺序读写函数 分组:(fgetc,fputc),(fgets,fputs),(f…

如何快速给word文件加拼音?请跟着步骤完成吧

如何快速给word文件加拼音&#xff1f;在日常工作中&#xff0c;我们时常会遇到需要为Word文件中的文字添加拼音的情况&#xff0c;这尤其在教育、出版或国际交流等领域显得尤为重要。为文字配上拼音&#xff0c;不仅能帮助学习者准确发音&#xff0c;还能提升文档的可读性和普…

3.6.xx版本SpringBoot创建基于Swagger接口文档

介绍 基于Swagger构建的JavaAPI文档工具&#xff0c;实现后端功能的测试&#xff0c;并撰写API接口文档。 方法 pom.xml中引入依赖,要注意的是&#xff0c;本依赖使用的SpringBoot版本为3.6.xx <!--Knife4j--><dependency><groupId>com.github.xiaoymin<…

W25Q64学习 非易失性存储器

嵌入式开发之Nand-Flash和Nor-Flash的区别_nand flash谁定义的-CSDN博客 w25q64是nor FLash 用SPI通信 W25Q64模块硬件电路&#xff0c;这里的HOLD,WP功能都没用到 对于w25q64整个存储空间&#xff0c;划分为128个块&#xff0c;对于每个块&#xff0c;划分为16个扇区&#…

【python实操】python小程序之如何使用私有公有属性和方法

引言 python小程序之如何使用私有公有 文章目录 引言一、如何使用私有公有属性和方法1.1 题目1.2 代码1.3 代码解释1.3.1 逐行解释1.3.1 代码行为总结 二、思考2.1 名称修饰2.2 总结 一、如何使用私有公有属性和方法 1.1 题目 如何使用私有公有属性、方法 1.2 代码 class P…

Python快速编程小案例——打印蚂蚁森林植树证书

提示&#xff1a;&#xff08;个人学习&#xff09;&#xff0c;案例来自工业和信息化“十三五”人才培养规划教材&#xff0c;《Python快速编程入门》第2版&#xff0c;黑马程序员◎编著 蚂蚁森林是支付宝客户端发起“碳账户”的一款公益活动:用户通过步行地铁出行、在线消费等…

华为云应用侧Android Studio开发

本文将介绍如何使用AndroidStudio开发APP完成与接入华为云IoTDA设备的对接&#xff0c;包括属性参数获以及取命令下发。 一、鉴权认证 应用侧需要通过IAM服务鉴权&#xff0c;获取token&#xff0c;华为账号创建 IAM 用户&#xff0c; 可以为创建的用户分配权限 认证鉴权_设…

开源全文搜索(搜索引擎)

吃水不忘挖井人&#xff0c;介绍Doug Cutting大牛是十分有必要的。 最早&#xff0c;接触到搜索引擎&#xff0c;知道有个Nutch&#xff08;开源搜索引擎&#xff09;&#xff0c;于是开始查看Nutch相关的资料&#xff0c;发现了Nutch的创始人Doug Cutting&#xff0c;随着项目…

Python 如何使用 Redis 作为缓存

Python 如何使用 Redis 作为缓存 一、引言 在现代 Web 应用程序和数据密集型服务中&#xff0c;性能 和 响应速度 是至关重要的因素。而当应用需要频繁访问相同的数据时&#xff0c;直接从数据库获取数据会耗费大量的时间和资源。因此&#xff0c;缓存系统成为了提升性能的重…

做一只由 OpenCV 控制的仿生手

这个项目介绍了如何制作和控制一只仿生手。作者最初受到Instagram上一个视频的启发&#xff0c;该视频展示了使用MPU6050传感器追踪手部动作并在屏幕上显示3D模型。作者决定将这个想法进一步发展&#xff0c;使用OpenCV来控制一只真实的仿生手。 大家好&#xff0c;在这篇教程中…

强大的PDF到Word转换工具

Solid Converter&#xff1a;强大的PDF到Word转换工具推荐 在日常工作和学习中&#xff0c;PDF是最常用的文件格式之一。然而&#xff0c;编辑PDF文档并不总是那么方便&#xff0c;尤其是当你需要将PDF文件转换为Word文档时。Solid Converter 是一款强大的工具&#xff0c;专为…

SpringBoot美发门店系统:数据驱动的决策

3系统分析 3.1可行性分析 通过对本美发门店管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本美发门店管理系统采用SSM框架&#xff0c;JAVA作为开发语…

7.并发编程之并发安全问题

1 线程安全性 什么是线程安全性&#xff1f;可以这么理解&#xff0c; 我们所写的代码在并发情况下使用 时&#xff0c;总是能表现出正确的行为&#xff1b;反之&#xff0c;未实现线程安全的代码&#xff0c;表现的行为是不可预知的&#xff0c;有可能正确&#xff0c;而绝大多…

九寨沟,智慧旅游新名片

九寨沟属于自然类景区&#xff0c;以优美的自然风光取胜&#xff0c;景区文化内涵相对缺失。智慧化和文旅融合是智慧文旅景区的两个必备条件&#xff0c;九寨沟在智慧文旅景区建设过程中&#xff0c;经历了两个阶段&#xff0c;先是从传统景区迈向智慧景区&#xff0c;然后是充…