zoukankan      html  css  js  c++  java
  • 【题解】 P2613 【模板】有理数取余

    题目

    题目描述

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

    输入格式

    一共两行。

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

    输出格式

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

    输入输出样例

    输入

    233
    666

    输出

    18595654

    说明/提示
    对于所有数据 (0 <= a,b <= 10^{10001})

    分析

    模意义下,除以一个数等于乘它的逆元

    高精度??输入long long化

    因为可以随时对MOD = 19260817取余,所以可以用快读,边读边取余,最后得到一个int类型的a和b,而不用高精度存储

    快速幂求逆元

    注意到模数19260817是个质数,我们求b在模它意义下的逆元

    由欧拉定理,若x,p互质,则(x ^ phi(p)/equiv 1(mod p))
    若p是个质数,(phi(p)=p-1),就有(x^{p-1}/equiv 1(mod p))
    在模p意义下,x的逆元是(x ^ {p - 2})
    即b的逆元是(b ^ {19260817 - 2})

    使用快速幂
    代码

    ll quick_mi_inv(ll c){
    	ll t = MOD - 2;
    	ll res = 1;
    	while(t){
    		if(t & 1){
    			res *= c;
    		}
    		c = c*c;
    		t >>= 1;
    		c %= MOD;
    		res %= MOD;
    	}
    	return res;
    }
    

    线性求逆元

    //求1~n在模p意义下的逆元
    //跟这个题没关系

    int inv[N] , n , p;
    cin >> n >> p;
    inv[1]=1;
    for (int i = 2 ; i <= n ; i++)
    
    {
    
        int a = p / i;
        
        int b = p % i;
        
        inv[i] = (p - inv[b]*a) % p;
    }
    

    Angry!

    因为0不能作除数,若b=0,无解
    逆元的存在?
    因为p是质数,所以b和p互质(如果不互质,b模完就成0了),所以b在模p意义下的逆元一定存在
    综上所述:
    当且仅当b=0时,输出"Angry!"

    没了然后就代码了

    代码实现

    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define F(a,b,c) for(int a = b; a <= c; a++)
    #define UF(a,b,c) for(int a = b; a >= c; a--)
    #define MOD 19260817 
    using namespace std;
    typedef long long ll;
    ll a, b, c; 
    ll read(){
    	char c = getchar();
    	int f = 1;
    	ll res = 0;
    	while(c < '0' || c > '9'){
    		if(c == '-')	f = -1;
    		c = getchar();
    	}
    	while(c <= '9' && c >= '0'){
    		res *= 10;
    		res += c - '0';
    		res %= MOD;
    		c = getchar();
    	}
    	return res * f;
    }
    
    ll quick_mi_inv(ll c){
    	ll t = MOD - 2;
    	ll res = 1;
    	while(t){
    		if(t & 1){
    			res *= c;
    		}
    		c = c*c;
    		t >>= 1;
    		c %= MOD;
    		res %= MOD;
    	}
    	return res;
    }
    int main(){
    	a = read();
    	b = read();
    	if(b == 0){
    		cout << "Angry!" << endl;
    		return 0;
    	}
    	b = quick_mi_inv(b);
    	cout << (a * b % MOD + MOD) % MOD << endl;
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    uboot中setenv和saveenv分析
    DMA和通道的区别
    openwrt 切换overlay文件系统为根文件系统
    华为SDN:解决传统网络3大问题
    企业需要申请多大宽带的专线?如何节省专线费用?
    stp
    inotify文件监控
    Qt中C++与QML交互
    内核空间可以直接访问应用层空间地址
    linux 提权漏洞总结
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/12368684.html
Copyright © 2011-2022 走看看