中国剩余定理 poj1006 模板

Posted 清酒令

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中国剩余定理 poj1006 模板相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=1006

题意:每个人的体力,情感,智力周期分别为23,28和33天。一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。通常这三个周期的峰值不会是同一天。现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。

分析:中国剩余定理的板子题

23,28,33满足两两互质,故直接套板子即可

 

先上模板:

//n个方程:x=a[i](mod m[i]) (0<=i<n)
LL china(int n, LL *a, LL *m){
    LL M = 1, ret = 0;
    for(int i = 0; i < n; i ++) M *= m[i];
    for(int i = 0; i < n; i ++){
        LL w = M / m[i];
        ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    }
    return (ret + M) % M;
}

然后代码

#include<cstdio>
typedef long long LL;
const int N = 100000 + 5;
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    if (!b) {d = a, x = 1, y = 0;}
    else{
        ex_gcd(b, a % b, y, x, d);
        y -= x * (a / b);
    }
}
LL inv(LL t, LL p){//如果不存在,返回-1 
    LL d, x, y;
    ex_gcd(t, p, x, y, d);
    return d == 1 ? (x % p + p) % p : -1;
}
LL china(int n, LL *a, LL *m){//中国剩余定理 
    LL M = 1, ret = 0;
    for(int i = 0; i < n; i ++) M *= m[i];
    for(int i = 0; i < n; i ++){
        LL w = M / m[i];
        ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    }
    return (ret + M) % M;
}
int main(){
    LL p[3], r[3], d, ans, MOD = 21252;
    int cas = 0;
    p[0] = 23; p[1] = 28; p[2] = 33;
    while(~scanf("%I64d%I64d%I64d%I64d", &r[0], &r[1], &r[2], &d) && (~r[0] || ~r[1] || ~r[2] || ~d)){
        ans = ((china(3, r, p) - d) % MOD + MOD) % MOD;
        printf("Case %d: the next triple peak occurs in %I64d days.\\n", ++cas, ans ? ans : 21252);
    }
    
}

 

以上是关于中国剩余定理 poj1006 模板的主要内容,如果未能解决你的问题,请参考以下文章

poj 1006(中国剩余定理+模板题)

poj1006-biorhythms中国剩余定理

[Poj1006]生理周期 (中国剩余定理)

poj 1006Biorhythms(数论--中国剩余定理 模版题){附中国剩余定理 }

中国剩余定理算法详解 + POJ 1006 Biorhythms 生理周期

Java-POJ1006-Biorhythms(中国剩余定理)