[日常训练]mod

Description

给定$p_1,p_2,…,p_n,b_1,b_2,...,b_m$,

求满足$x;mod;p_1;equiv;a_1,x;mod;p_2;equiv;a_2,...,x;mod;p_n;equiv;a_n$的$x$对$b_1,b_2,...,b_m$取模的结果.

Input

第一行两个整数$n,m$.

接下来$n$行,每行有一个整数$a_i$.

接下来$m$行,每行有一个整数$b_i$.

Output

$m$行,每行一个整数,表示$x;mod;b_i$的结果.

Sample Input

4 3

1

2

3

2

11

23

100

Sample Output

1

0

23

HINT

$m=100,0<b_i<10^9,b_i$为随机生成的,$p_i$为第$i$小的质数.

Solution

中国剩余定理+高精度???

这题只需记录$mod;b_i$结果.

$ans.b[i]$表示$mod;b_i$的结果,$mul.p[i]$表示目前$p_i$寻找答案中每次加上的数,$ans.p[i],mul.b[i]$同理.

对于$i;in;[1,n]$,每次暴力$+mul.p[i]$直到$ans.p[i]=a_i$,然后将每个$mul.p[;];; imes;p[i]$(保证后面无论怎么操作,$ans.p[i];equiv;a_i(mod;p_i)$.

($ans.b[;],mul.b[;]$同步进行以上$"+"," imes"$操作.)

#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 305
#define M 2000
using namespace std;
typedef long long ll;
struct mod{
    int p[N];ll b[N];
}ans,mul;
ll b[N]; 
int a[N],p[N],n,m,cnt;
bool u[M],flag;
inline void prime(){
    for(int i=2;cnt<n;++i){
        if(!u[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<M;++j){
            u[p[j]*i]=true;
            if(!(i%p[j])) break; 
        }
    }
}
inline void init(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        if(a[i]) flag=true;
    }
    for(int i=1;i<=m;++i)
        scanf("%lld",&b[i]);
    prime();
    if(!flag){
        for(int i=1;i<=m;++i){
            ans.b[i]=1LL%b[i];
            for(int j=1;j<=n;++j)
                ans.b[i]=ans.b[i]*(ll)(p[j])%b[i];
        }
        for(int i=1;i<=m;++i)
            printf("%lld
",ans.b[i]);
        return;
    }
    for(int i=1;i<=n;++i)
        mul.p[i]=1%p[i];
    for(int i=1;i<=m;++i)
        mul.b[i]=1LL%b[i];
    for(int i=1;i<=n;++i){
        while(ans.p[i]!=a[i]){
            for(int j=1;j<=n;++j)
                ans.p[j]=(ans.p[j]+mul.p[j])%p[j];
            for(int j=1;j<=m;++j)
                ans.b[j]=(ans.b[j]+mul.b[j])%b[j];
        }
        for(int j=1;j<=n;++j)
            mul.p[j]=mul.p[j]*p[i]%p[j];
        for(int j=1;j<=m;++j)
            mul.b[j]=mul.b[j]*(ll)(p[i])%b[j];
    } 
    for(int i=1;i<=m;++i)
        printf("%lld
",ans.b[i]);
}
int main(){
    freopen("mod.in","r",stdin);
    freopen("mod.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/AireenYe/p/6240495.html