zoukankan      html  css  js  c++  java
  • hdu1576

    博客图片

    题目链接

    hdu1576

    题目概述

    要求((A/B)\%9973),但由于A很大,我们只给出(n(n=A\%9973))(我们给定的A必能被B整除,且(gcd(B,9973) = 1)).

    数据的第一行是一个(T),表示有(T)组数据。
    每组数据有两个数(n(0 leq n < 9973))(B(1 leq B leq 10^9)).

    对应每组数据输出((A/B)\%9973).

    解题思路

            利用逆元算除法取模的概念题,当然求逆元也可以用费马小定理来做.

    扩展欧几里得

            对于一个二元一次方程(ax+by=n, \, a,b,nin Z)当且仅当(gcd(a,b)=n)时方程有整数解.这个方程的解是先找到一个整数解((x_0,y_0)),然后通解:

    [egin{cases} x = x_0 + bt \ y = y_0 - at, qquad t in Z end{cases} ]

    把通解带入原来的方程得到:

    [egin{aligned} ax+by &= a(x_0+bt)+b(y_0-at)\ &= ax_0+by_0 + (abt - bat)\ &= n qquad(ecause ax_0+by_0=n) end{aligned} ]

    所以只要求出一个特解原方程的通解就可以求出.

    扩展欧几里得对应的代码如下,可以求得方程(ax+by=gcd(a,b))的一个特解((x_0+y_0)).

    void extend_gcd(ll a, ll b, ll & x, ll & y) {
        if( b == 0ll){
            x = 1;
            y = 0;
            return;
        }
        extend_gcd(b, a % b, x, y);
        ll temp = x;
        x = y;
        y = temp - (a / b) * y;
    }
    

    逆元

            如果(a pmod m = b pmod m),那么称(a,b)(n)同余,记做(a equiv bpmod m).(ax equiv b pmod m)成为一元线性同余方程,即(ax-b)(m)的整数倍,从而(ax-b=my),可以得到(ax+my=b),当(b=gcd(a,m))时可以用扩展欧几里得来解.可以使用逆元来解上面方程的任意情形,设(a')(a pmod m)的逆元,即(aa'equiv1 pmod m).将上面的等式同时乘以(a'),得到(a'axequiv a'b pmod m),即(xequiv a'b pmod m).

            对于方程(ax equiv1pmod m,)(gcd(a,m)=1)时,相当于解方程(ax + my = 1.)用前面的扩展欧几里得就可求出一个特解.

    ll mod_inverse(ll a, ll m){
        ll x, y;
        extend_gcd(a, m, x, y);
        return ( m + x % m)% m;
    }
    

    利用费马小定理求逆元

    (p)为素数,(gcd(a,p) = 1),那么(a^{p-1} equiv 1pmod p).
    另外一种形式:对于(ain Z, a^p equiv apmod p)

    由上面的费马小定理可以推出方程(ax equiv 1pmod m,gcd(a,m)=1)的解(x = a^{m-1}).利用快速幂取模可以进行计算.

    ll fast_exp_mod(ll a, ll b, ll p){
        ll ans = 1;
        while( b ){
            if( b & 1){
                ans = (ans * a) % p;
            }
            b >>= 1;
            a = (a * a) % p;
        }
        return ans;
    }
    
    ll mod_inverse(ll a, ll m){
        return fast_exp_mod(a, m - 2, m) % m;
    }
    

    代码实现

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    
    const int M = 9973;
    
    ll fast_exp_mod(ll a, ll b, ll p){
        ll ans = 1;
        while( b ){
            if( b & 1){
                ans = (ans * a) % p;
            }
            b >>= 1;
            a = (a * a) % p;
        }
        return ans;
    }
    
    void extend_gcd(ll a, ll b, ll & x, ll & y) {
        if( b == 0ll){
            x = 1;
            y = 0;
            return;
        }
        extend_gcd(b, a % b, x, y);
        ll temp = x;
        x = y;
        y = temp - (a / b) * y;
    }
    
    ll mod_inverse(ll a, ll m){
        // ll x, y;
        // extend_gcd(a, m, x, y);
        // return ( m + x % m)% m;
        return fast_exp_mod(a, m - 2, m) % m;
    }
    
    int main(int argc, const char** argv) {
        int T;
        scanf("%d", &T);
        for (int i = 0; i < T; ++i){
            int n, b;
            scanf("%d%d", &n, &b);
            ll ans = mod_inverse(b, M);
            ans = (ans * n) % M;
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    其它

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters
    记一次odoo创建新的模块时,但是在odoo web界面找不到应用的案例
    python实现格式化输出9*9乘法表
    format和urlencode的使用对比
    python字典小知识
    01
    深浅拷贝再回顾
    DRF的路由生成类的使用
  • 原文地址:https://www.cnblogs.com/2018slgys/p/13329062.html
Copyright © 2011-2022 走看看