• 【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 }
  • 相关阅读:
    PPP协议 PAP认证
    交换机广播风暴,STP生成树协议,端口聚合
    传统远程注入线程,加载DLL
    EXE和DLL调用关系,DLL制作,钩子
    window bat批处理 实用脚本
    python利用scapy嗅探流量
    关于AWD线下攻防的经验
    APP 仿微信登录
    价值1500左右的毕业设计都开源啦
    EOS2.0环境搭建-centos7
  • 原文地址:https://www.cnblogs.com/chty/p/6021068.html
Copyright © 2020-2023  润新知