数论模板集合

本文深入探讨了多种数学算法,包括最大公约数、逆元、快速幂、卡塔兰数、矩阵快速幂、斯特灵近似、质数判定、欧拉筛法、欧拉函数、分解质因数、二元一次不定方程解法以及排列组合问题,提供了丰富的代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

gcd

  1. //欧几里得,又叫做最大公约数
  2. int gcd(int a,int b)
  3. {
  4.     return b==0?a:gcd(b,a%b);
  5. }
  6. int gcd(int big, int small)
  7. {
  8.     if (small > big) swap(big, small);
  9.     int temp;
  10.     while (small != 0){ //  辗转相除法
  11.         if (small > big) swap(big, small);
  12.         temp = big % small;
  13.         big = small;
  14.         small = temp;
  15.     }
  16.     return(big);
  17. }


逆元

  1. //逆元
  2. gcd(a,b)=a*x+b*y;
  3. gcd(b,a%b,)
  4. ll extgcd(ll a,ll b,ll &x,ll &y)
  5. {
  6.     if(b==0){
  7.         x=1,y=0;
  8.         return a;
  9.     }
  10.     ll d=extgcd(b,a%b,x,y);
  11.     ll t=x;
  12.     x=y;
  13.     y=t-a/b*y;
  14.     return d;
  15. }
  16. ll inv(ll a,ll mod)
  17. {
  18.     ll x,y;
  19.     extgcd(a,mod,x,y);
  20.     return (mod+x%mod)%mod;
  21. }

快速幂

  1. ll fast_pow(ll a,ll b,ll mod)
  2. {
  3.     ll ans=1;
  4.     while(b){
  5.         if(b&1)ans=ans*a%mod;
  6.         a=a*a%mod;
  7.         b>>=1;
  8.     }
  9.     return ans;
  10. }
  11. //快速幂


卡塔兰数

  1. #define ll long long
  2. ll Catelan[N];
  3. //用逆元求解
  4. ll extgcd(ll a, ll b, ll& x, ll& y)
  5. {
  6.     ll d = a;
  7.     if(b != 0){
  8.         d = extgcd(b, a % b, y, x);
  9.         y -= (a / b) * x;
  10.     }else {
  11.         x = 1;
  12.         y = 0;
  13.     }
  14.     return d;
  15. }
  16. void pre()
  17. {
  18.     int i;
  19.     ll x, y;
  20.     Catelan[0] = 1, Catelan[1] = 1;
  21.     for(i = 2; i < N-5; i++)
  22.     {
  23.         Catelan[i] = Catelan[i-1]*(4*i-2) % mod;
  24.         extgcd(i+1, mod, x, y);
  25.         Catelan[i] = (Catelan[i]*((x+mod)%mod)) % mod;
  26.     }
  27. }

矩阵快速幂求逆元

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define MAXN 100
  5. #define LL long long
  6. #define MOD 10000
  7. using namespace std;
  8. struct Matrix
  9. {
  10.     LL a[MAXN][MAXN];
  11.     int r, c;//行数 列数
  12. };
  13. Matrix ori, res;//初始矩阵 和 结果矩阵
  14. void init()//初始化矩阵
  15. {
  16.     memset(res.a, 0, sizeof(res.a));
  17.     res.r = 2; res.c = 2;
  18.     for(int i = 1; i <= 2; i++)//构造单位矩阵
  19.         res.a[i][i] = 1;
  20.     ori.r = 2; ori.c = 2;
  21.     ori.a[1][1] = ori.a[1][2] = ori.a[2][1] = 1;
  22.     ori.a[2][2] = 0;
  23. }
  24. Matrix multi(Matrix x, Matrix y)
  25. {
  26.     Matrix z;
  27.     memset(z.a, 0, sizeof(z.a));
  28.     z.r = x.r, z.c = y.c;//新矩阵行数等于x矩阵的行数 列数等于y矩阵的列数
  29.     for(int i = 1; i <= x.r; i++)//x矩阵的行数
  30.     {
  31.         for(int k = 1; k <= x.c; k++)//矩阵x的列数等于矩阵y的行数 即x.c = y.r
  32.         {
  33.             if(x.a[i][k] == 0) continue;//优化
  34.             for(int j = 1; j<= y.c; j++)//y矩阵的列数
  35.                 z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % MOD) % MOD;
  36.         }
  37.     }
  38.     return z;
  39. }
  40. void Matrix_mod(int n)
  41. {
  42.     while(n)//N次幂
  43.     {
  44.         if(n & 1)
  45.             res = multi(ori, res);
  46.         ori = multi(ori, ori);
  47.         n >>= 1;
  48.     }
  49.     printf("%lld\n", res.a[1][2] % MOD);
  50. }
  51. int main()
  52. {
  53.     int N;
  54.     while(scanf("%d", &N), N!=-1)
  55.     {
  56.         init();//初始化单位矩阵
  57.         Matrix_mod(N);//矩阵快速幂
  58.     }
  59.     return 0;
  60. }

斯特灵近似

  1. ll steling(ll n)
  2. {
  3.     return ll(log10(sqrt(4*acos(0.0)*n))+n*log10(n/exp(1.0)))+1;
  4. }

原文:https://blog.youkuaiyun.com/jamence/article/details/81660163

判定质数

  1. for(int i = 2 ; i * i <= n ; ++i) {
  2.     if( n % i == 0 )
  3.     {
  4.         flag = 1 ;
  5.         breke;
  6.     }

欧拉筛法
求  n 以内的所有质数

  1. for(int i = 2 ; i <= n ; ++ i ) {
  2.     if( ! vis[i] )
  3.     {
  4.         cnt ++ ;
  5.         p[cnt] = i ;
  6.     }
  7.     for( int j = 1 ; j <= cnt && i * p[j] <= n ; ++ j )
  8.     {
  9.         vis[p[j] * i ] = 1 ;
  10.         if( i % p[j] == 0 ) break;
  11.     }
  12. }

欧拉函数

方法一

  1. scanf("%lld", &n );
  2.         if( n == 0 )
  3.             return 0;
  4.         long long m = n ;
  5.         for(int i = 2 ; i * i <= m ; ++ i )//分解为质数乘积
  6.         {
  7.             if( m % i == 0 )
  8.             {
  9.                 cnt ++ ;
  10.                 p[cnt] = i ;
  11.                 while( m % i == 0 )
  12.                 {
  13.                     m = m / i ;
  14.                     w[cnt] ++ ;
  15.                 } 
  16.             }
  17.         }
  18.         if( m != 1 )
  19.         {
  20.             cnt ++ ;
  21.             p[cnt] = m ;
  22.             w[cnt] = 1 ;
  23.         }
  24.         long long ans = 1 ;
  25.         for(int i = 1 ; i <= cnt ; ++ i )
  26.         {
  27.             ans = ans * (p[i] - 1 ) ;
  28.             for(int j = 1 ; j < w[i] ; j ++ )
  29.             {
  30.                 ans = ans *p[i] ;
  31.             }
  32.         }

方法二

  1. ph[1] = 1 ;//结合欧式筛法,可以求出 n 以内每一个数的欧拉函数值
  2.     scanf("%d", &n );
  3.     for(int  i = 2 ; i <= n ; ++ i ) {
  4.         if(!vis[i]) {
  5.             cnt ++ ;
  6.             pr[cnt] = i ;
  7.             ph[i] = i - 1 ;
  8.         }
  9.         for(int j = 1 ; j <= cnt && i * pr[j] <= n ; ++ j ) {
  10.             vis[ i * pr[j] ] = 1 ;
  11.             if( i % pr[j] == 0 ) {
  12.                 ph[ pr[j] * i ] = ph[i] * pr[j] ;
  13.                 break;
  14.             }
  15.             else
  16.                 ph [ pr[j] * i] = ph[i] * (pr[j] - 1 );
  17.         }
  18.     }
     


原文:https://blog.youkuaiyun.com/qq_44013342/article/details/88023526 

分解质因数

(任何一个大于1的自然数,都能分解为若干个质数的幂的乘积,即n=p_{1}^{w_{1}}*p_{2}^{w^{2}}*......*p_{m}^{w_{m}}

  1. void get(int n)
  2. {
  3.     for(int i = 2;i * i <= n;i++)
  4.         if (n % i == 0){
  5.             p[++m] = i;
  6.             while(n % i == 0){
  7.                 w[m]++;
  8.                 n /= i;
  9.             }
  10.         }
  11.     if (n != 1){
  12.         p[++m] = n;
  13.         w[m] = 1;
  14.     }
  15. }

欧拉函数
求n以内与n互质的自然数的个数。先求出如上所述的“p”与“w”,再用以下公式:

sum=n*(1-\tfrac{1}{p_{1}})*(1-\tfrac{1}{p_{2}})*......*(1-\tfrac{1}{p_{m}})

或者

sum=p_{1}^{w_{1}-1}*(p_{1}-1)*p_{2}^{w_{2}-1}*(p_{2}-1)*......*p_{m}^{w_{m}-1}*(p_{m}-1)

求二元一次不定方程的整数解
二元一次不定方程形如:ax+by=c(a、b、c是已知参数),当c是gcd(a,b)的倍数时(gcd(a,b)表a和b的最大公因数),才有整数解。可以用某种算法(即扩展欧几里得算法)求出不定方程ax+by=gcd(a,b)的解(此处x、y不等于上述x、y,因为在算法中把c看作了gcd(a,b),所以解出来x、y缩小了c/gcd(a,b))。

最后求整数解的通解,用如下公式:

x'=x+b/gcd(a,b)*t;

y'=y-a/gcd(a,b)*t;

其中t为任意整数

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. using namespace std;
  5. int d,x,y;
  6. void Sgcd(int a,int b,int &d,int &x,int &y){     //d、x、y要放在全局
  7.     if (b == 0){
  8.         x = 1;
  9.         y = 0;
  10.         d = a;
  11.         return;
  12.     }
  13.     else{
  14.         Sgcd(b,a % b,d,y,x);
  15.         y -= a / b * x;
  16.     }
  17. }
  18. int main()
  19. {
  20.     int a,b,c;
  21.     scanf("%d%d%d",&a,&b,&c);
  22.     Sgcd(a,b,d,x,y);
  23.     int m = c / d;
  24.     printf("%d %d\n",x * m,y * m);//特殊解
  25.     printf("%d %d\n",x * m + b / d,y * m - a / d);//其中一个通解,t=1;
  26.     return 0;
  27. }

排列组合

一、基本公式

(特殊的,0!=1)(以下n>=m)

排列A_{n}^{m}=\frac{n!}{(n-m)!}

表示从n个数中取出m个数来排列的方案总数,忽略顺序。例如:m=2时,(1,2)是一种,(2,1)是另一种。

 

组合:C_{n}^{m}=\frac{n!}{m!(n-m)!}=C_{n-1}^{m-1}*n/m

表示从n个数中取出m个数来组合的方案总数,限制顺序。可以理解为从n个数中取出m个数有多少种取法。例如:m=2时,(1,2)和(2,1)是同一种。m=3时,(1,2,3)和(1,3,2)以及(2,1,3)等是同一种。

二、经典例题

1、将n个相同的球放进m个不同的盒子里。球要放完,盒子不能为空,问有多少种放法。

解:题目等价于有n个球,要在两个球之间插板子(两个球之间最多能插一个),将球分为m个部分。n个球,有n-1个空隙可以插;m个部分,只用m-1个板子。

 

所以又可以等价于有n-1个板子,只需要取m-1个板子,问有多少种取法。因为反正都是把球分为m个部分,所以不同的板子得到的效果是一样的,所以可以理解为是同一种取法。这就是组合。答案:C_{n-1}^{m-1}

 

2、将n个相同的球放进m个不同的盒子里。球要放完,盒子可以为空,问有多少种放法。

解:假设盒子不可以为空,放在此题种就等价于你已经放了m个球,还有n个球。所以此题等价于有n+m个球,放在m个盒子里,球要放完,盒子不能为空,这就是第一题了。答案:C_{n+m-1}^{m-1}

 

3.将n个不同的球放在m个相同的盒子里。要求每个盒子里球的数量一样,球要放完(数据保证m是n的因子),问有多少种方法。

解:设n/m=x,即每个盒子里要放x个球。放球时,第一步:在n个球中取出x个球放在一个空盒里,第二步又在剩下的n-x个球中取出x个球放在一个空盒里......直至放完。所以第一步的方法总数是:C_{n}^{x},到第二步的方法总数是:C_{n}^{x}*C_{n-x}^{x},一共m步,以此类推。但是有这种情况:已经以某一种方案按要求将所有球放进m个盒子里了,现在却只是将A盒里的球放进B盒里,将B盒里原来的球放进A盒里。因为盒子是一样的,所以这是同一种方法。但计算时却以为是另一种方法。而这个等价于:已经以某一种方案按要求将所有球放进m个盒子里了,现在却只是将盒子调换位置,却认为是不同的方法。调换位置的方法有A_{m}^{m}个。所以最后还要减去A_{m}^{m}。答案:C_{n}^{x}*C_{n-x}^{x}*......*C_{x}^{x}-A_{m}^{m}

原文:https://blog.youkuaiyun.com/weixin_44025325/article/details/87289230 

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是与HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,与RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法与创新点。1.1研究背景与意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法与创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论与技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述与后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计与实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计与实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试与优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法与步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论与展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望与改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户与权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋与房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋与房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置与完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间与原因) 3. 住宿分配与调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修与安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值