zoukankan      html  css  js  c++  java
  • 【codevs3990】中国余数定理2

    【题目描述】
    Skytree神犇最近在研究中国博大精深的数学。
    这时,Sci蒟蒻前来拜访,于是Skytree给Sci蒟蒻出了一道数学题:
    给定n个质数,以及k模这些质数的余数。问:在闭区间[a,b]中,有多少个k?最小的k是多少?
    Sci蒟蒻数学能力差了Skytree三条街,所以他只好寻求计算机的帮助。他发邮件给同为oier的你,你能帮他解决这个问题吗?

    【题解】

    用中国剩余定理求出最小的k,然后k+M*y都是可能的值,所以个数就是(b-k)/M+1

    注意在统计答案时,由于模数M可能过大,要使用快速乘。

     1 /*************
     2   CODEVS 3990
     3   by chty
     4   2016.11.1
     5 *************/
     6 #include<iostream>
     7 #include<cstdio>
     8 #include<cstring>
     9 #include<cstdlib>
    10 #include<cmath>
    11 #include<ctime>
    12 #include<algorithm>
    13 using namespace std;
    14 typedef long long ll;
    15 ll n,l,r,ans,M(1),a[15],m[15];
    16 inline ll read()
    17 {
    18     ll x=0,f=1;  char ch=getchar();
    19     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    20     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    21     return x*f;
    22 }
    23 void exgcd(ll a,ll b,ll &x,ll &y)
    24 {
    25     if(b==0)  {x=1; y=0; return;}
    26     exgcd(b,a%b,x,y);
    27     ll t=x;x=y;y=t-a/b*y;
    28 }
    29 ll mul(ll x,ll y){return ((x*y-(ll)(((long double)x*y+0.5)/M)*M)%M+M)%M;}//一行快速乘
    30 int main()
    31 {
    32     freopen("cin.in","r",stdin);
    33     freopen("cout.out","w",stdout);
    34     n=read();  l=read();  r=read();
    35     for(ll i=1;i<=n;i++)  m[i]=read(),a[i]=read(),M*=m[i];
    36     for(ll i=1;i<=n;i++)
    37     {
    38         ll x,y,Mi=M/m[i];
    39         exgcd(Mi,m[i],x,y);
    40         ans=(ans+mul(mul(x,Mi),a[i]))%M;
    41     }
    42     if(ans<l||ans>r)  printf("0
    0
    ");
    43     else printf("%lld
    %lld
    ",(r-ans)/M+1,ans);
    44 }
  • 相关阅读:
    OUT还开通博客!
    《超越想象——Windows_8应用设计与开发》
    kissy初体验(一)
    网页乱码!!!
    一起学习extjs()
    程序员你不懂爱,博客园就要倒下来。。
    如何用WordPress做网站?
    程序员,你懂的.
    Windows 8 应用开发技术资源
    开源easyui.selectdialog
  • 原文地址:https://www.cnblogs.com/chty/p/6021068.html
Copyright © 2011-2022 走看看