zoukankan      html  css  js  c++  java
  • [POJ 2891] Strange Way to Express Integers

    Description

    给定 k 个同余方程组,求出满足条件的最小正整数 x,或者无解输出 -1。

    Solution

    注意到模数不一定互质,所以中国剩余定理不能用

    嗯有请扩展中国剩余定理

    定理证明就不说了右转置顶博文

    讲一下这道题怎么搞

    假设我们已经把若干个式子合并为一个了,模数为 A,余数为 R。

    那么对于新式子$k_1 imes A + R = k_2 imes a_i + r_i$

    可以通过移项搞出来 $k_1 imes A + k_2 imes a_i = r_i - R$

    发现了什么? 扩欧直接套上去啊!

    等等,如果要判断有没有解怎么办?

    中国剩余定理告诉我们此方程有解当且仅当 $gcd(A,a_i) mid (r_i-R)$

    那么我们就可以通过这一步判断是否应该输出 -1

    然后我们扩欧瞎搞搞出来当前方程的解了:$k_1' imes A + k_2' imes a_i = gcd(A,a_i)$

    之后呢?注意到求出来的 $k_1'$ 不是原方程的解,原方程的解应该是 $k_1 = k_1' imes frac{r_i - R}{gcd(A,a_i)}$。

    这一步很重要,因为 $k_1$ 有可能不是正数,所以要 $k_1 \%=frac{a_i}{gcd(A,a_i)}$,这样才保证了 $k_1$ 是个正数。

    然后就把 $k_1$ 代进关于 $x$ 的表达式即可求出 $x$ 的值。

    还没完。当前求出来的 $x$ 只是这两个方程的特解,不是整个方程的通解。

    我们设 $ans$ 为最后的答案。

    易证 $ans equiv x quad(mod;lcm(A,a_i))$

    咦?这不是一个新的同余方程了么?

    那我们是将两个同余方程合并成一个了啊。

    就这样消下去最后只剩下一个同余方程就是最后答案了啊。

    没错就是这样=.=

    Code

     1 #include<cstdio>
     2 #include<cctype>
     3 #define N 100005
     4 #define int long long
     5 
     6 signed k;
     7 int a[N],r[N];
     8 
     9 int exgcd(int a,int b,int &x,int &y){
    10     if(!b){
    11         x=1,y=0;
    12         return a;
    13     }
    14     int c=exgcd(b,a%b,x,y);
    15     int t=x;
    16     x=y;
    17     y=t-a/b*y;
    18     return c;
    19 }
    20 
    21 int CRT(){
    22     int A=a[1],R=r[1];
    23     int x,y;
    24     for(int i=2;i<=k;i++){
    25         int d=exgcd(A,a[i],x,y);
    26         if((r[i]-R)%d) return -1;
    27         x*=(r[i]-R)/d;
    28         int zj=a[i]/d;
    29         ((x%=zj)+=zj)%=zj;
    30         //x%=a[i]/d;
    31         R+=x*A;
    32         //A=A/d*a[i];
    33         A=A*a[i]/d;
    34     }
    35     int X=R;
    36     X%=A;
    37     X+=A;
    38     X%=A;
    39     return X;
    40 }
    41 
    42 signed main(){
    43     while(~(scanf("%d",&k))){
    44         for(int i=1;i<=k;i++) scanf("%lld%lld",&a[i],&r[i]);
    45         printf("%lld
    ",CRT());
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    The path "" is not valid path to the gcc binary.
    ADB命令介绍
    Android 中Message,MessageQueue,Looper,Handler详解+实例
    Sqlite 修改字段
    曾经光辉岁月 永远海阔天空
    用AchartEngineActivity引擎自定义图表控件和背景折线图
    一个帖子学会Android开发四大组件
    Android获得系统时间(24小时制)
    TagBuilder
    MVC
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/8948023.html
Copyright © 2011-2022 走看看