• C++ P2613 【模板】有理数取余


    题目描述

    给出一个有理数c=frac{a}{b},求c mod 19260817的值。

    输入输出格式

    输入格式:

    一共两行。

    第一行,一个整数a。
    第二行,一个整数b。

    输出格式:

    一个整数,代表求余后的结果。如果无解,输出Angry!

    输入输出样例

    输入样例#1: 

    233
    666
    

    输出样例#1: 

    18595654
    

    说明

    对于所有数据,0leq a,b leq 10^{10001}


     个人思路:

    • 一开始还以为直接a/b就行了,后来发现范围太大了(而且frac{aoldsymbol{mod}P}{boldsymbol{mod}P}
eq frac{a}{b}oldsymbol{mod}P
    • 看了一下题解,思路是用费马小定理(a^{P-1}equiv 1(oldsymbol{mod }P))求逆元即可(因为p刚好是质数)
    • 也就是说,因为a*b=1,所以a*b=a^{P-1} 
ightarrow a^{P-2}=b
    • 在获取数字的过程中,为了避开使用高精度,一位一位地读,每读完一位就%一次P即可保证数字不超范围(取模的基本性质)
    • 因为我们利用了取模的基本性质,所以最终答案当然不能直接a/b,所以我们需要用快速幂求b,也就是计算a^{P-2},也就计算出了b的值
    • 之后,a与b相乘并模P即可

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ll long long
    using namespace std;
    int p=19260817;
    char c[10010];
    int read(){
    	scanf("%s",c);
    	ll length=strlen(c);
    	ll num=0;
    	for(int i=0;i<length;i++){
    		num*=10;
    		num+=(c[i]-'0');
    		num=num%p;
    	}
    	return num;
    }
    long poww(ll a,ll b){
    	long ans=1;
    	while(b){
    		if(b&1){
    			ans=(ans*a)%p;
    		}
    		a=(a*a)%p;
    		b=b>>1;
    	}
    	return ans;
    }
    int main(){
    	ll a,b;
    	a=read(),b=read();
    	if(b==0){
    		cout<<"Angry!"<<endl;
    		return 0;
    	} 
    	cout<<a*poww(b,p-2)%p<<endl;
    	return 0;
    }
  • 相关阅读:
    检查使用的端口
    time is always agains us
    检查使用的端口
    dreque问题一例
    查看重定向的输出
    安装VSS时,Um.dat may be corrupt
    修改网卡ip
    redis install on ubuntu/debian
    上火了
    学这么多技术是为什么
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680678.html
Copyright © 2020-2023  润新知