# 2超时,求助
查看原帖
# 2超时,求助
1229671
Greenqwq楼主2024/5/10 21:43
//因为这里是每一项,所以它跟CRT很有关系(中国剩余定理)
//(n-ai)同余0(mod bi)

#include<iostream>
#include<algorithm>
#define int long long
using namespace std;

const int N = 12;

int a[N],b[N];
int n;
int M=1;//模数

int qmul(int a,int b){
    int res=0;
    
    while(b){
        if(b&1)res=(res+a)%M;
        a=(a+a)%M;
        b>>=1;
    }
    return res;
}

int exgcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

int CRT(){
    
    int res=0;
    for(int i=1;i<=n;i++){
        int m=M/b[i];
        // cout<<"m="<<m<<endl;
        int x=0,y=0;
        //这里是要算乘法逆元
        //x=sigema(r(同余数)*m*m^{-1})
        //求m的逆元mx=1(mod b[i])
        //乘法逆元两种算法,当n为质数,我们就用费马小定理求解
        //a^(p-1)≡1(mod p) 当p为质数才能适用, 因此a^(p-2)就是a的乘法逆元,本质就是求a^(p-2) % p 快速幂
        //当n不为质数,用exgcd
        exgcd(m,b[i],x,y);
        x=(x%b[i]+b[i])%b[i];//x要模也是模y上的系数
        res=((res+qmul(qmul(x,m),a[i]))%M+M)%M;
    }
    return res;
}

signed main(){
    scanf("%lld",&n);
    
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)scanf("%lld",&b[i]),M*=b[i];
    
    printf("%lld",CRT());
    
    return 0;
}
2024/5/10 21:43
加载中...