zoukankan      html  css  js  c++  java
  • poj1006 Biorhythms

    CRT板子

    注意题目要求ans>d 其实就是减完d再%M+M%M

    一开始英文看成了1天输出单数....输出格式还是复制的好

    中国剩余定理

    给定n组同余方程 形如x≡a[i](mod m[i])的形式 求解x

     > Q:没有明显的思路嘤嘤嘤

    这个.....那我们拆成不定方程

    x = k[i] * m[i] + a[i]

    x = k[j] * m[j] + a[j]

    然后方程组联立求k[]就好了对不对

    (啪!)

    (这个方法确实是行的...就是不好写 又叫 合并法)

    但是它并不是我们今天要说的Chinese Remainder Theorem

    这个是一种解所有m[]互质的特殊情况的算法

    换句话说 就是利用

    若 n = pq 且 gcd( p , q )= 1 ,那么 x mod p , x mod q 的值确定后, x mod n 的值也会随之确定。

    可以O(n*O(gcd))求解 

    算法流程:

    考虑对于每一个m[i] 求一个数t[i]使得

    t[i] % m[j] = 0 (j != i)

    t[i] % m[j] = 1 (j == i)

    这样对于所有的i (1~n)∑t[i]*a[i] 就是答案

    (因为t[i]是m[j]的倍数 mod 的时候会消掉)

    但是t[i]怎么求呢

    考虑先满足第一个条件 我们就求一个rev[i]表示LCM / m[i]

    然后求一个rev[i]的倍数 满足mod m[i] == 1

    也就是r[i] * x + m[i] * y = 1

    这不就是exgcd吗!

    最后t[i]就是r[i] * x

    至此 就 做完了

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #include<vector>
     7 #define ms(a,b) memset(a,b,sizeof a)
     8 #define rep(i,a,n) for(int i = a;i <= n;i++)
     9 #define per(i,n,a) for(int i = n;i >= a;i--)
    10 #define inf 2147483647
    11 #define eps 1e-8
    12 using namespace std;
    13 typedef long long ll;
    14 ll read() {
    15     ll as = 0,fu = 1;
    16     char c = getchar();
    17     while(c < '0' || c > '9') {
    18         if(c == '-') fu = -1;
    19         c = getchar();
    20     }
    21     while(c >= '0' && c <= '9') {
    22         as = as * 10 + c - '0';
    23         c = getchar();
    24     }
    25     return as * fu;
    26 }
    27 const int N = 100005;
    28 ll gcd(ll a,ll b) {return b ? gcd(b,a%b) : a;}
    29 //head
    30 const int M = 21252;
    31 ll d;
    32 ll a[3],r[3],t[3],m[3] = {23,28,33};
    33 ll exgcd(ll a,ll b,ll &x,ll &y) {
    34     if(!b) {
    35         x = 1,y = 0;
    36         return a;
    37     }
    38     ll t = exgcd(b,a%b,y,x);
    39     y -= (a/b) * x;
    40     return t;
    41 }
    42 int main() {
    43     ll y,tot = 0;
    44     r[0] = 28*33,r[1]=23*33,r[2]=23*28;
    45     rep(i,0,2) {
    46         exgcd(r[i],m[i],t[i],y);
    47         t[i] = ((t[i]%M)+M)%M;
    48         t[i] = r[i] * t[i] % M;
    49     }
    50     while(1) {
    51         scanf("%lld%lld%lld%lld",a,a+1,a+2,&d);
    52         if(a[0] == -1 && a[1] == -1 && a[2] == -1 && d == -1) break;
    53         ll ans = 0;
    54         rep(i,0,2) ans = (ans + t[i] * a[i]) % M;
    55         ans = (ans%M+M)%M;
    56         if(ans <= d) ans+=M;
    57         printf("Case %d: the next triple peak occurs in %lld days.
    ",++tot,ans-d);
    58     }
    59     return 0;
    60 }
    View Code
    > 别忘了 总有人在等着你
  • 相关阅读:
    Linux系统下ping命令报错 name or service not know
    利用Kettle进行SQLServer与Oracle之间的数据迁移实践
    STS中配置MyBatis代码生成器
    GeoServer中配置GeoWebCache切片缓存目录
    Win10下安装msi程序包时报2503、2502错误问题及其解决办法
    常用办公软件推荐
    Excel中使用VBA进行度分秒与十进制度的转换
    ArcGIS下图层范围不正确的两种处理方式
    更改GeoServer的端口号
    Tomcat跨域访问配置
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/9780642.html
Copyright © 2011-2022 走看看