数论——线性同余方程、扩欧求解线性同余方程、线性组合、原根求解

news2025/1/24 8:48:09
线性同余方程

线性同余方程是形如  的方程,其中a 、b、m 为给定的整数,x 是未知整数。

扩欧求解线性同余方程
void mod_slover(int a, int b, int n) {
    int d, x, y, x0;
    d = extend_gcd(a, n, x, y);
    if (b % d != 0)
        cout << "no answer";
    else
        x0 = x * (b / d) % n;
    for (int i = 0; i <= d - 1; i++)
        cout << x0 + i * (n / d) % n;
}
#include <iostream>

// 扩展欧几里得算法
int extendedEuclidean(int a, int b, int& x, int& y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }

    int x1, y1;
    int gcd = extendedEuclidean(b, a % b, x1, y1);

    x = y1;
    y = x1 - (a / b) * y1;

    return gcd;
}

// 求解线性同余方程
bool solveLinearCongruence(int a, int b, int m, int& x) {
    int x0, y0;
    int gcd = extendedEuclidean(a, m, x0, y0);

    if (b % gcd!= 0) {
        return false;  // 无解
    }

    int mod = m / gcd;
    x = (x0 * (b / gcd)) % mod;
    if (x < 0) {
        x += mod;  // 保证解为正数
    }

    return true;
}

int main() {
    int a = 3, b = 2, m = 5;
    int x;

    if (solveLinearCongruence(a, b, m, x)) {
        std::cout << "Solution of " << a << "x ≡ " << b << " (mod " << m << ") is: x = " << x << std::endl;
    } else {
        std::cout << "No solution exists." << std::endl;
    }

    return 0;
}
  • extendedEuclidean 函数用于计算两个数的最大公约数,并同时得到一组满足  的解 x0 和 y0 。

  • solveLinearCongruence 函数首先调用 extendedEuclidean 计算 a 和 m 的最大公约数 gcd 。如果 b 不能被 gcd 整除,则方程无解。

  • 若有解,计算出一个特解 x ,并通过取模操作和调整使其落在合法范围内(大于等于 0 且小于 m / gcd )。

欧拉定理解线性同余方程

#include <iostream>

// 计算欧拉函数
int eulerPhi(int n) {
    int result = n;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            result -= result / i;
            while (n % i == 0) {
                n /= i;
            }
        }
    }
    if (n > 1) {
        result -= result / n;
    }
    return result;
}

// 快速幂取模
int quickPow(int a, int b, int mod) {
    int res = 1;
    while (b) {
        if (b & 1) {
            res = (long long)res * a % mod;
        }
        a = (long long)a * a % mod;
        b >>= 1;
    }
    return res;
}

// 利用欧拉定理求解线性同余方程
bool solveLinearCongruenceEuler(int a, int b, int m, int& x) {
    if (std::__gcd(a, m)!= 1) {
        return false;  // a 和 m 不互质,无解
    }

    int phi = eulerPhi(m);
    int invA = quickPow(a, phi - 1, m);  // a 的逆元

    x = (long long)invA * b % m;
    return true;
}

int main() {
    int a = 3, b = 2, m = 5;
    int x;

    if (solveLinearCongruenceEuler(a, b, m, x)) {
        std::cout << "Solution of " << a << "x ≡ " << b << " (mod " << m << ") is: x = " << x << std::endl;
    } else {
        std::cout << "No solution exists." << std::endl;
    }

    return 0;
}
  • eulerPhi 函数用于计算给定整数的欧拉函数值,通过遍历质因数并进行相应的计算得到结果。

  • quickPow 函数用于快速计算幂的模运算。

  • solveLinearCongruenceEuler 函数首先判断  a和m  是否互质,如果不互质则方程无解。然后计算  的欧拉函数值,找到  a的逆元,最后计算出 x 的值。

线性组合
线性同余方程组(模互素)

#include <iostream>

// 扩展欧几里得算法
int extendedEuclidean(int a, int b, int& x, int& y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }

    int x1, y1;
    int gcd = extendedEuclidean(b, a % b, x1, y1);

    x = y1;
    y = x1 - (a / b) * y1;

    return gcd;
}

// 计算模逆元
int modInverse(int a, int m) {
    int x, y;
    int gcd = extendedEuclidean(a, m, x, y);
    if (gcd!= 1) {
        std::cout << "Inverse doesn't exist" << std::endl;
        return -1;
    } else {
        return (x % m + m) % m;
    }
}

// 中国剩余定理求解
int chineseRemainderTheorem(int a[], int m[], int n) {
    int M = 1;
    for (int i = 0; i < n; i++) {
        M *= m[i];
    }

    int x = 0;
    for (int i = 0; i < n; i++) {
        int Mi = M / m[i];
        int invMi = modInverse(Mi, m[i]);
        x += a[i] * Mi * invMi;
    }

    return x % M;
}

int main() {
    int a[] = {2, 3, 2};
    int m[] = {3, 5, 7};
    int n = sizeof(a) / sizeof(a[0]);

    int result = chineseRemainderTheorem(a, m, n);
    std::cout << "Solution of the system is: " << result << std::endl;

    return 0;
}
中国剩余定理

int CRT(const int a[],const int m[],int n){
    int M = 1, ret = 0;
    for (int i = 1; i <= n; ++i)
        M *= m[i];
    for (int i = 1; i <= n; ++i) {
        int Mi = M / m[i], ti = inv(Mi, m[i]);
        ret = (ret + a[i] * a[i] * Mi * ti) % M;
    }
    return ret;
}
int inverse(int a, int b) {
    int x, y;
    excend_gcd(a, b, x, y);
    return x;
}

第一类高次同余方程
第二类高次同余方程
 原根的解法
【模板】原根

登录—专业IT笔试面试备考平台_牛客网

#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
using ll = long long;
const int N=1e6+7;
int pr[N],ph[N],fc[9],u[11],v[11],a[N];
bool f[N],b[N],p[N],q[N];
void init(int n){//线性筛,b数组记录是否有原根
	b[2]=b[4]=ph[1]=1;
	int i,j,k,t=0;
	for(i=2;i<=n;++i){
		if(!f[i])pr[++t]=i,ph[i]=i-1;
		for(j=1;k=i*pr[j],k<=n&&j<=t;++j){
			f[k]=1;
			if(!(i%pr[j])){
				ph[k]=ph[i]*pr[j];
				break;
			}
			ph[k]=ph[i]*ph[pr[j]];
		}
	}
	for(i=2;i<=t;++i){
		for(j=1;j*1ll*pr[i]<=n;b[j*=pr[i]]=1);
		for(j=2;j*1ll*pr[i]<=n;b[j*=pr[i]]=1);
	}
}
int qp(int a,int b,int p){
	int r=1;
	while(b){
		if(b&1)r=r*1ll*a%p;
		a=a*1ll*a%p,b>>=1;
	}
	return r;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T,n=0,m,d,i,j,k,t,o,s;
	cin>>T;
	for(i=1;i<=T;++i)cin>>u[i]>>v[i],n=n>u[i]?n:u[i];
	init(n);
	for(o=1;o<=T;++o){
		n=u[o],d=v[o];
		if(!b[n]){
			cout<<0<<"\n"<<endl;//如果没有原根;
			continue;
		}
		for(i=1,j=m=ph[n],t=0;1ll*pr[i]*pr[i]<=j;++i){
			if(!(j%pr[i])){
				fc[++t]=s=pr[i];//求出phi(n)的质因子;
				do j/=s;while(!(j%s));
				for(k=s;k<=m;k+=s)p[k]=1;
			}
		}
		if(j>1){
			fc[++t]=j;
			for(k=j;k<=m;k+=j)p[k]=1;
		}
		for(j=1;;++j){
			while(qp(j,m,n)!=1)++j;
			for(i=1;i<=t&&qp(j,m/fc[i],n)!=1;++i);
			if(i>t)break;//t个质因数都不符合
		}//快速幂求出最小原根j;
		for(t=j,i=1,s=0;i<=m;++i,t=t*1ll*j%n)
			if(!p[i])q[t]=1,++s;else p[i]=0;//通过最小原根求出所有原根
		cout<<s<<endl;
		for(i=1,j=0;i<n;++i){
			if(q[i]){
				q[i]=0,++j;
				if(j==d)j=0,cout<<i<<" ";
			}
		}//排序后从小到大输出;
		cout<<endl;
	}
	return 0;
}
  1. init 函数:

    • 这是一个线性筛法的函数,用于计算小于等于 n 的质数 pr 和每个数的欧拉函数值 ph,同时通过 b 数组标记是否有原根。
    • 首先对一些特殊情况(如 2 和 4)进行初始化。
    • 然后通过两层循环,筛选出质数并计算对应的欧拉函数值。对于每个数 i 和其对应的质数 pr[j],根据是否整除的情况计算 ph[k]
    • 接着通过另外的循环标记有原根的数。
  2. qp 函数:这是一个快速幂函数,用于计算 a 的 b 次幂对 p 取模的结果。

  3. main 函数:

    • 首先进行输入输出的同步设置。
    • 读入测试用例的数量 T 和每个用例中的 u[i] 和 v[i],并确定最大的 n 值。
    • 调用 init 函数进行预处理。
    • 对于每个测试用例:如果 n 没有原根,直接输出 0 并继续下一个用例。计算 phi(n) 的质因子并存放在 fc 数组中,同时标记相关的数。通过循环找到最小原根 j 。基于最小原根计算所有原根,统计原根的数量 s 并输出。按照要求输出第 d 个原根。
字符串的最大公约数

力扣1071.字符串的最大公因子

class Solution {
public:
    string gcdOfStrings(string str1, string str2) {
         return str1+str2!=str2+str1?"":str1.substr(0,gcd(str1.size(),str2.size()));
    }
};
  1. str1 + str2 != str2 + str1:这检查str1后跟str2是否与str2后跟str1不相等。如果它们相等,这意味着一个字符串可以被看作是另一个的旋转,可能意味着某种重复或模式。

  2. gcd(str1.size(), str2.size()):这计算str1str2长度的最大公约数(GCD)。GCD是能同时整除两者的最大数。

  3. str1.substr(0, gcd(str1.size(), str2.size())):如果第一个条件为真,它会返回str1从索引0开始,长度等于str1str2大小的GCD的子串。这对于找出字符串中的重复模式或重复的基本单元很有用。

如果第一个条件为假(即字符串能够以任意顺序拼接),则返回空字符串""

这种逻辑经常用于解决与字符串模式相关的问题,例如确定一个字符串是否是另一个字符串的旋转,或者找出字符串中最短的重复模式。

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

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

相关文章

联邦学习研究综述【联邦学习】

文章目录 0 前言机器学习两大挑战&#xff1a; 1 什么是联邦学习&#xff1f;联邦学习的一次迭代过程如下&#xff1a;联邦学习技术具有以下几个特点&#xff1a; 2 联邦学习的算法原理目标函数本地目标函数联邦学习的迭代过程 3 联邦学习分类横向联邦学习纵向联邦学习联邦迁移…

科普文:微服务之Spring Cloud OpenFeign服务调用调用过程分析

概叙 Feign和OpenFeign的关系 其实到现在&#xff0c;至少是2018年之后&#xff0c;我们说Feign&#xff0c;或者说OpenFeign其实是一个东西&#xff0c;就是OpenFeign&#xff0c;是2018.12 Netflix停止维护后&#xff0c;Spring cloud整合Netflix生态系统的延续。后面其实都…

ComfyUI-BrushNet(局部重绘)节点安装及效果、模型下载及详细使用方法✨

&#x1f35c;背景介绍 ComfyUI 中BrushNet的节点已经发布了三个月左右的时间了&#xff0c;后来陆续更新了更多的功能和模型接入&#xff0c;整体效果看起来还是不错的。这个节点随着能力的更新&#xff0c;接入了更多的模型&#xff0c;而每个模型默认的名字又比较相似&…

RoboDK的插件

目录 collision-free-planner&#xff1a; opc-ua&#xff1a; collision-free-planner&#xff1a; RoboDK 的无碰撞规划器插件使用概率路线图 (PRM) 自动在机器人工作空间内创建无碰撞路径。 有关无碰撞规划器的更多信息&#xff0c;请访问我们的 文档。 生成参数无碰撞…

揭秘:查询大数据信用报告的三大作用

相信很多朋友都听说过大数据信用是什么&#xff0c;其实早在几年前&#xff0c;不少的网贷平台都是用人行征信加上大数据信用作为平台风控审核的依据&#xff0c;直到大数据技术的发展&#xff0c;现在不少的银行等机构都将大数据信用作为银行放贷风控审核的重要指标&#xff0…

趋势跟踪策略 文华财经指标公式源码 九稳量化系统 多空趋势指标神器 期货起爆点买入指标源码

斯坦利•克罗 1、赢利时是长线&#xff0c;亏损时就是短线。 2、50%回调位金字塔加码&#xff0c;“坐”着赚钱&#xff0c;甚至不惜用鸵鸟政策&#xff0c;眼不见心不烦。 3、阻碍长线操作成功的最主要原因是觉得单调乏味和失去纪律。 4、把自己的止损点设在远离绝大多数投…

detr论文解读

参考&#xff1a;https://www.bilibili.com/video/BV1md4y1s7nW/?spm_id_from333.788&vd_source156234c72054035c149dcb072202e6be 补充&#xff1a;decoder更关注边缘特征 补充&#xff1a; spatial pos.enc.&#xff1a;空间位置编码。包含encoder和decoder的空间位置…

Flutter 2024: Impeller引擎引领渲染新纪元

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 Flutter 2024: Impeller引擎引领渲染新纪元 在移动应用开发领域&#xff0c;Flutter凭借其跨平台能力、丰富的组件库和高性能的渲染引擎&#…

OpenStack概述

一、初识OpenStack OpenStack Docs: 概况 一&#xff09;OpenStack架构简述 1、理解OpenStack OpenStack既是一个社区&#xff0c;也是一个项目和一个开源软件&#xff0c;提供开放源码软件&#xff0c;建立公共和私有云&#xff0c;它提供了一个部署云的操作平台或工具集&…

Linux 内核源码分析---通用文件模型及 VFS 结构

通用文件模型 通常一个完整的 Linux 系统由数千到数百万个文件组成&#xff0c;文件中存储了程序、数据和各种信息。层次化的目录结构用于对文件进行编排和分组。 ReiserFS&#xff08;新型的文件系统&#xff09;–>Reiser4 它通过一种与众不同的方式—完全平衡树结构来容…

高并发下的分布式缓存 | 设计和实现LRU缓存

LRU缓存介绍 什么是LRU缓存&#xff1f; LRU缓存是一种缓存策略&#xff0c;当缓存满了&#xff0c;需要腾出空间存放新数据时&#xff0c;它会删除最近最少使用的数据。换句话说&#xff0c;它会优先淘汰那些最久没有被访问的元素&#xff0c;以确保缓存中的数据是最近使用的…

学习安卓开发遇到的问题

问题1&#xff1a;学习禁用与恢复按钮中&#xff1a; java代码报错&#xff1a;报错代码是 R.id.btn_enable;case R.id.btn_disable;case R.id.btn_test: 代码如下&#xff1a;&#xff08;实现功能在代码后面&#xff09; package com.example.apptest;import static java.…

04 表的操作

目录 创建查看修改删除 1. 创建 语法&#xff1a; CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储殷勤; 说明&#xff1a; field&#xff0c;表示列名 datatype&#xff0c;表示列的类型…

专题十_哈希表

目录 题型总结 1. 两数之和 解析 题解 面试题 01.02. 判定是否互为字符重排 解析 题解 217. 存在重复元素 解析 题解 219. 存在重复元素 II 解析 题解 49. 字母异位词分组 解析 题解 题型总结 1. 两数之和 1. 两数之和 解析 题解 class Solution { public:ve…

ECMAScript 12 (ES12, ES2021) 新特性

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

Rewrite功能配置

Rewrite Rewrite是Nginx服务器提供的一个重要基本功能。主要的作用是用来实现URL的重写。 Nginx服务器的Rewrite功能的实现依赖于PCRE的支持&#xff0c;因此在编译安装Nginx服务器之前&#xff0c;需要安装PCRE库。 Nginx使用的是ngx_http_rewrite_module模块来解析和处理Re…

用VBA在Word中随机打乱单词表,进行分列

一、效果展示&#xff08;以下是三次随机打乱的结果&#xff09; 二、代码 Sub 随机分单词到后面的单元格()Dim C1 As CellDim str, str1, aDim shuffledArray() As VariantSet C1 Selection.Range.Tables(1).Cell(1, 1)str C1.Range.textstr mid(str, 3, Len(str) - 4)str…

微信小程序版NetAssist局域网工具使用

微信小程序搜《TCPUDP局域网小助手》即可使用&#xff0c;电脑端&#xff0c;安卓端&#xff0c;苹果端都可以使用

【前端面试】七、算法-递归、拷贝等

目录 1.常考算法 2.遍历方法 3.链式调用 4.递归 5.拷贝和比较 1.常考算法 排序算法&#xff1a;快速排序、归并排序、堆排序等。 查找算法&#xff1a;二分查找、哈希表查找等。 动态规划&#xff1a;解决最优化问题&#xff0c;如斐波那契数列、最长公共子序列等。 图…

8.3 day bug

bug1 文件名字写错了&#xff0c;找了半天bug原因 freecodecamp的致敬页的测试验证不通过bug 已经写了display: block;和max-width: 100% 以及通过margin: 0 auto;居中&#xff0c;可是却通不过验证 问了通义千问 通义帮我修改后的html代码为 <!DOCTYPE html> 2<h…