关于gcd和exgcd的一道ICPC题的解法与回顾部分知识点

news/2024/9/25 22:11:33

\(gcd\)的本质原理

\(gcd(x,y)\)\(gcd(y,\)x%y\()\)之所以等价
证明如下:
\(x\)\(y\)的本质公约数为d
\(x=m*d\),\(y=n*d\)
\(x/y=k\)
\(x\)%y\(==x-x/y*y==m*d-k*n*d==(m-n*k)d\)
如果\(x\)\(y\)的倍数,则\(m-n*k==0\),返回\(y\)
否则,数值缩小进一步靠近最大公约数
代码

ll gcd(ll a, ll b) {if (b == 0) return a;else return gcd(b, a % b);
}

\(exgcd(x,y,x1,y1)\)的原理

\(exgcd(x,y,x1,y1)\)能求出对于一个方程\(ax+by=gcd(x,y)\)符合条件的\(x\)\(y\),其中返回\(x1=x\),\(y1=y\)
\(y==0\)时,\(x1=1,y=0\)\(exgcd(x,y,x1,y1)=gcd(x,y)\)的唯一正解
又加上
\(gcd(x,y)=gcd(y,x\)%\(y)\)
所以\(a0x+b0y=a1y+(x\)%\(y)b1=a1y+(x-x/y*y)b1=b1*x+(a1-x/y*b1)y\)
\(a0=b1,bo=a1-x/y*b1\)
于是递归得解
代码

void exgcd(ll x, ll y, ll &x1, ll &y1)
{if (y == 0){x1 = 1;y1 = 0;return;}
exgcd(y, x % y, x1, y1);ll t = x1;x1 = y1;y1 = t - x / y *y1 ;
}

裴蜀定理

对于非负整数\(a,b\),存在\(x,y\)使得\(ax+by=gcd(a,b)\),即\(ax+by\)能构成的最小正整数就是\(gcd(a,b)\)\(a,b\)不可同时为0
多理解即可

题目时间!!!

Modulo Ruins the Legend

题目链接,QOJ:https://qoj.ac/problem/5301
codforces:https://codeforces.com/gym/104090/problem/A

#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<bitset>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<time.h>
#include<random>
using namespace std;
typedef long long ll;
mt19937 rnd(time(0));
ll gcd(ll a, ll b) {if (b == 0) return a;else return gcd(b, a % b);
}
ll ksm(ll x, ll y)
{ll ans = 1;while (y){if (y & 1)ans *= x;x *= x;y >>= 1;}return ans;
}
void fio()
{ios::sync_with_stdio();cin.tie(0);cout.tie(0);
}
ll a[100500];
void exgcd(ll a, ll b, ll &x, ll &y)
{if (b == 0){x = 1;y = 0;return;}
exgcd(b, a % b, x, y);ll t = x;x = y;y = t - a / b * y;
}
int main()
{fio();ll n, m;cin >> n >> m;ll sum = 0;for (ll i = 1; i <= n; i++){cin >> a[i];sum += a[i];}ll x = gcd(n, n * (n + 1) / 2);ll y = gcd(x, m);//裴蜀定理,求最小,随后移项会变成k1*y=-sum+kll k = y - (y - sum % y);//最小的k,直接先求最小值k,最后k等价于sum%yll j = -sum / y;//y其实乘以了jcout << k << endl;//如何求逆解?ll x1, y1;exgcd(x, m, x1, y1);ll x2, y2;x1 = (x1 % m * (j % m)) % m;//最后答案是模m的,先把j乘上,最后再对m取模exgcd(n, n * (n + 1) /2 , x2, y2);x2 =x2%m*(x1%m)%m;y2 =(y2%m* (x1%m))%m;cout << (x2 % m + m) % m << " " << (y2 % m + m) % m<<endl;
}

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

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

相关文章

9-12

9段好的,我会逐句翻译并解释其中的关键词汇及其发音。 1. **There are, of course, people belonging to all classes who do not want to be fascinated and then enslaved by Admass, and who if necessary are ready to make a few sacrifices, largely material, to achie…

“人民冻凉”简介

账号定位: 这是一个由 复旦大学 的学生运营的 非官方自媒体账号 。 它最大的标签就是 复旦。 其次是复旦附带的的 \(985\)、江浙沪、上海交大、清北华五 这类的 \(\text{tag}\) 。 可以简单理解为,这是一个上海版的 全元光滑 。但实际上,考虑到两者在 学校的地域、创始团队的…

02 深浅拷贝关于 str int bool

深浅拷贝 list /set /dict 一层

河道污染物识别系统

河道污染物识别系统通过深度学习技术,河道污染物识别系统对监控画面中河道污染物以及漂浮物进行全天候实时监测,当河道污染物识别系统监测到河道水面出现污染物时,立即抓拍存档触发告警并同步通知相关人员及时处理。河道污染物识别系统利用河道两旁现场摄像头可及时发现河道…

05 字典内存分配

data_list = [] for i in range(10):data = {}data[user] = idata_list.append(data) print(data_list) #每个字典都 不一样字典,列表内存指向图 data = {} for i in range(10):data[user] = i print(data)内存占用图

00 内存分配 -- 重点

要确认是进行赋值,还是找到其中, 有赋值为:重新开辟内存空间 python 将:-5~ 256为常用的数字(如果在范围类使用同一内存空间,这叫:python小数据池) 如果大于这个数值,会重新 进行开僻内存空间 字符串:如果A1 = ‘’alex A2= ‘alex , A1/A2等于同一个字符串 ,理应不…

01 内存地址 示例

示例一: v1 = [11,22,33] v2 = [11,22,33] v1 = 666 v2 = 666v1 = "asdf" v2 = "asdf"#以上数据都不是同一个内存地址# 按理 v1 和 v2 应该是不同的内存地址。特殊: 1. 整型: -5 ~ 256 2. 字符串:"alex",asfasd asdf asdf d_asdf …