• [POJ 2891]Strange Way to Express Integers(扩展中国剩余定理)


    Description

    Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:

    Choose k different positive integers a1a2…, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1a2, …, ak are properly chosen, m can be determined, then the pairs (airi) can be used to express m.

    “It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”

    Since Elina is new to programming, this problem is too difficult for her. Can you help her?

    Solution

    扩展中国剩余定理的板子题

    证明的话可以看zyf2000的博客(我太懒了),个人感觉讲的还是比较清楚啦

    注意数据最好还是一次性输入,这题的RE可能是因为无解break之后剩下的数据没有读入进来

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define MAXN 50005
    using namespace std;
    typedef long long LL;
    LL k,c[MAXN],m[MAXN];
    LL read()
    {
        LL x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    void exgcd(LL a,LL b,LL &d,LL &x,LL& y)
    {
        if(!b)d=a,x=1,y=0;
        else exgcd(b,a%b,d,y,x),y-=x*(a/b);
    }
    LL inv(LL a,LL p)
    {
        LL d,x,y;exgcd(a,p,d,x,y);
        return (x+p)%p==0?p:(x+p)%p;
    }
    int main()
    {
        LL m1,m2,c1,c2;
        while(~scanf("%lld",&k))
        {
            for(int i=1;i<=k;i++)
                m[i]=read(),c[i]=read();
            for(int i=2;i<=k;i++)
            {
                m1=m[i-1],m2=m[i],c1=c[i-1],c2=c[i];
                LL t=gcd(m1,m2);
                if((c2-c1)%t!=0){c[k]=-1;break;}
                m[i]=m1*m2/t;
                c[i]=inv(m1/t,m2/t)*((c2-c1)/t)%(m2/t)*m1+c1;
                c[i]=(c[i]%m[i]+m[i])%m[i];
            }
            printf("%lld
    ",c[k]);
        }
        return 0;
    }
  • 相关阅读:
    Linux学习笔记之Linux Centos关闭防火墙
    ELK学习笔记之Logstash详解
    ELK学习笔记之ElasticSearch的索引详解
    C语言拼接字符串 -- 使用strcat()函数
    linux 中的 open() read() write() close() 函数
    stderr 和stdout
    ubuntu14.04 放开串口权限
    ubuntu14.04 安装 openssh-server
    串口接线
    ubuntu + usb转RS232驱动
  • 原文地址:https://www.cnblogs.com/Zars19/p/6986248.html
Copyright © 2020-2023  润新知