以上是中国剩余定律的适用问题(专门用于解线性同余方程)
题意描述:见https://www.luogu.org/problemnew/show/P3868
解题思路:参考https://www.luogu.org/problemnew/solution/P3868
我觉得要注意的地方有两点
1.快速乘可以防止爆long long。这个很有趣,以前一直用的都是快速幂,没想到快速乘有这种妙用。
2.ai可能存在负数,需要将其变成正数。其实如果不用快速乘倒是无所谓ai的正负。但是用了快速乘,ai必须得是正的,而且应该前面进行mod,可以减小快速乘的运算量。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[15],b[15];
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;
}
ll mul(ll x,ll b,ll mod)
{
ll ans=0,res=x;
while(b)
{
if(b&1) ans=(ans+res)%mod;
b>>=1;
res=(res+res)%mod;
}
return ans;
}
int main()
{
//freopen("t.txt","r",stdin);
int k;
scanf("%d",&k);
ll sum=1;
for(int i=0;i<k;i++) scanf("%lld",&a[i]);
for(int i=0;i<k;i++) scanf("%lld",&b[i]),sum*=b[i];
for (int i=0; i<k;i++) a[i]=((a[i]%b[i])+b[i])%b[i];
ll x,y,ans=0;
for(int i=0;i<k;i++)
{
ll t=sum/b[i];
exgcd(t,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
//ans=(ans+t*a[i]*x)%sum;
ans=(ans+mul(mul(t,a[i],sum),x,sum))%sum;
}
cout<<ans;
return 0;
}