中国剩余定理
程序员文章站
2022-05-22 10:35:21
...
中国剩余定理模板代码
#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
#define int long long
const int N = 2e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b == 0) x = 1,y = 0;
else
{
exgcd(b,a%b,y,x);
y -= x*(a/b);
}
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n;
cin >> n;
ll m[n+5],a[n+5],Lcm = 1,ans = 0;
for(int i = 0;i < n;i++)
{
cin >> m[i] >> a[i];
Lcm *= m[i];
}
for(int i = 0;i < n;i++)
{
ll num = Lcm/m[i],x,y;
exgcd(num,m[i],x,y);
ans = ans + a[i]*num*(x < 0 ? x+m[i] : x);//x可能为负数
ans %= Lcm;
}
cout << ans << endl;
return 0;
}
扩展中国剩余定理模板
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;
lt read()
{
lt f=1,x=0;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
const int maxn=100010;
int n;
lt ai[maxn],bi[maxn];
lt mul(lt a,lt b,lt mod)
{
lt res=0;
while(b>0)
{
if(b&1) res=(res+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return res;
}
lt exgcd(lt a,lt b,lt &x,lt &y)
{
if(b==0){x=1;y=0;return a;}
lt gcd=exgcd(b,a%b,x,y);
lt tp=x;
x=y; y=tp-a/b*y;
return gcd;
}
lt excrt()
{
lt x,y,k;
lt M=bi[1],ans=ai[1];//第一个方程的解特判
for(int i=2;i<=n;i++)
{
lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//ax≡c(mod b)
lt gcd=exgcd(a,b,x,y),bg=b/gcd;
if(c%gcd!=0) return -1; //判断是否无解,然而这题其实不用
x=mul(x,c/gcd,bg);
ans+=x*M;//更新前k个方程组的答案
M*=bg;//M为前k个m的lcm
ans=(ans%M+M)%M;
}
return (ans%M+M)%M;
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
bi[i]=read(),ai[i]=read();
printf("%lld",excrt());
return 0;
}
下一篇: 奇怪的一件事 微信开发 请教
推荐阅读
-
2020支付宝额外的福卡怎么得 可口可乐安慕希中国移动星巴克福获得方法
-
抖音发财中国年怎么得发字金卡 2020抖音集齐钻石卡流程攻略
-
抖音集卡怎么获得翻倍卡使奖金翻倍 抖音发财中国年翻倍卡怎么得
-
2020抖音发财中国年怎么快速集卡 抖音发财中国年集卡攻略
-
抖音集卡发字获得方法 抖音发财中国年什么卡最难得
-
抖音集卡分5亿钻卡是什么 2020抖音发财中国年钻卡玩法攻略
-
2020年抖音发财中国年的金卡和钻卡有什么区别 分别是什么意思
-
2021年校友会中国大学排名完整版最新(500强)
-
中国著名大学排名前十有哪些高校?附全国名校大学排名最新完整版名单汇总
-
2021全国排名前十大学-中国大学国内排名最新排名(前十强)