码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P3811线性求逆元

时间:2017-08-14 14:19:04      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:bsp   blog   for   就会   线性   ret   rac   names   code   

首先扩O:T了一个点(因为上界松),83分。

#include <cstdio>
using namespace std;

int n, p;

void exgcd(int a, int p, int &b, int &x){
    if (p==0){
        b=1, x=0;
        return;
    } 
    exgcd(p, a%p, b, x);
    int tmp=b;
    b=x;
    x=tmp-a/p*x;
    return;
}

int main(){
    scanf("%d%d", &n, &p);
    int x, y;
    for (int i=1; i<=n; ++i){
        exgcd(i, p, x, y);
        printf("%d\n", (x+p)%p);
    }
    return 0;
}

然后费马,事实证明果然更慢,上界很紧。

#include <cstdio>
using namespace std;

int n, p;

int expower(int a, int pow, int mod){
    int ans=1;
    while (pow){
        if (pow&1) ans=1LL*ans*a%mod;
        a=1LL*a*a%mod;
        pow>>=1;
    }
    return ans;
}

int main(){
    scanf("%d%d", &n, &p);
    for (int i=1; i<=n; ++i){
        printf("%d\n", expower(i, p-2, p));
    }
    return 0;
}

正解:首先$1^{-1} \equiv 1 \pmod p$

我们设:$p = k\cdot i + r,~r < i,~1 < i < p$

将其放在模p意义下:$k\cdot i + r \equiv 0 \pmod p$

两边同乘i-1,r-1就会得到:

$\begin{eqnarray*} k\cdot r^{-1} + i^{-1} &\equiv& 0 &\pmod p\\ i^{-1} &\equiv& -k\cdot r^{-1} &\pmod p\\ i^{-1} &\equiv& -\left\lfloor\frac{p}{i}\right\rfloor\cdot \left(p\bmod i\right)^{-1} &\pmod p\ \end{eqnarray*}$

于是核心代码就一行: 

A[i] = -(p / i) * A[p % i];

我的代码:

注意:有可能是负数

#include <cstdio>
using namespace std;

const int maxn=3000000;
int n, p, a[maxn];

int main(){
    scanf("%d%d", &n, &p);
    a[1]=1;
    printf("%d\n", a[1]);
    for (int i=2; i<=n; ++i){
        a[i]=(1LL*-(p/i)*a[p%i])%p;
        a[i]=(a[i]+p)%p;
        printf("%d\n", a[i]);
    }
    return 0;
}

luogu P3811线性求逆元

标签:bsp   blog   for   就会   线性   ret   rac   names   code   

原文地址:http://www.cnblogs.com/MyNameIsPc/p/7357327.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!