51nod 数论专题 (按分值排序)(持续更新)

1 .51nod 1011

gcd,不解释

代码:

int gcd(a, b){
    return b ? gcd(b, a%b) : a;
}

2 .51nod 1135

求最小原根

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define mem(a,b) memset(a, b, sizeof(a))
#define LL long long

using namespace std;

const int maxn = 1000005;

int yue[maxn], tot, cnt;
int v[maxn], prime[maxn]; 

void is_prime(){
    mem(v,1);
    for(int i = 2; i <= maxn; i++){
        if(v[i]){
            prime[++cnt] = i;
            for(int j = i; j <= maxn; j += i){
                v[j] = 0;
            }
        }
    }
}

void div(int x){
    tot = 0;
    int t = (int)sqrt(1.0*x);
    for(int i = 1; prime[i] <= t; i++){
        if(x % prime[i] == 0){
            yue[++tot] = prime[i];
            while(x % prime[i] == 0) x /= prime[i];
        }
    }
    if(x > 1)
        yue[++tot] = x;
}

LL Pow(LL a, LL b, LL m){
    LL ans = 1;
    a %= m;
    while(b){
        if(b & 1)
            ans = ans * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return ans;
}


int main(){
    int p;
    is_prime();
    while(scanf("%d", &p) == 1 && p){
        div(p-1);
        for(int i = 2; i <= p-1; i++){
            bool flag = 1;
            for(int j = 1; j <= tot; j++){
                int t = (p-1)/yue[j];
                if(Pow((LL)i, (LL)t, (LL)p) == 1){
                    flag = 0;
                    break;
                }
            }
            if(flag){
                printf("%d\n", i);
                break;
            }
        }
    }
return 0;
}

3 .51nod 1046

快速幂

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define LL long long

using namespace std;

LL Pow(LL a, LL b, LL p){
    LL ans = 1LL;
    a %= p;
    while(b){
        if(b & 1)
            ans = ans * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ans;
}

int main(){
    LL a, b, c;
    scanf("%lld%lld%lld", &a, &b, &c);
    printf("%lld\n", Pow(a, b, c));
return 0;
}

4. 51nod 1073

约瑟夫环

代码:

#include <iostream>

using namespace std;
int main(){
    int n, k;
    cin>>n>>k;
    int s = 0;
    for(int i = 1; i <= n; i++){
        s = (s + k) % i;
    }
    cout<<s+1<<endl;
return 0;
}

5. 51nod 1256

乘法逆元(因为N不一定是素数,所以用exgcd求解)

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define LL long long

using namespace std;

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

int main(){
    LL a, b, x, y;
    scanf("%lld%lld", &a, &b);
    exgcd(a, b, x, y);
    x = (x % b + b) % b;
    printf("%lld\n",x);
return 0;
}

6. 51nod 1136

求欧拉函数值

代码:

#include <iostream>
#include <cmath>

using namespace std;

int phi(int n){
    int ans = n;
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0){
            ans = ans / i * (i-1);
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1)   ans = ans / n * (n-1);
    return ans;
}

int main(){
    int n;
    cin>>n;
    cout<<phi(n)<<endl;
return 0;
}

7 .51nod 1079

中国剩余定理

推荐博客:https://blog.csdn.net/acdreamers/article/details/8050018

https://www.cnblogs.com/MashiroSky/p/5918158.html

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#define LL long long

LL exgcd(LL a, LL b, LL &x, LL &y){
    if(!b){
        x = 1, y = 0;
        return a;
    } 
    int d = exgcd(b, a%b, x, y);
    int tmp = x;
    x = y;
    y = tmp - (a/b)*y;
    return d;
}

LL CSD(int m[], int a[], int n){
    LL x  = 0, y, d;
    LL M = 1;
    LL ans = 0;
    for(int i = 1; i <= n; i++){
        M *= m[i];
    }
    for(int i = 1; i <= n; i++){
        LL Mi = M / m[i];
        d = exgcd(Mi, m[i], x, y);
        x = x/d;
        ans = (ans + a[i]*Mi*x) % M;
    }
    return (ans + M) % M;
}

int main(){
    int n, m[15], a[15];
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d %d", &m[i], &a[i]);
    }
    printf("%lld\n", CSD(m, a, n));
return 0;
}

8. 51nod 1240

莫比乌斯(mobius)函数

代码:

//求单个数的mobius值
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int c[1000005];

int main(){
    int n, ans = 0, m = 0;
    scanf("%d", &n);
    int nn = n;
    for(int i = 2; i <= sqrt(nn); i++){
        if(n % i == 0){
            c[++m] = 0;
            while(n % i == 0){
                n /= i;
                c[m]++;
            }
        }
    }   
    if(n > 1){
        c[++m] = 1;
    }
    for(int i = 1; i <= m; i++){
        if(c[i] >= 2){
            printf("0\n");
            return 0;
        }
    }
    if(m & 1){
        printf("-1\n");
    }
    else{
        printf("1\n");
    }
return 0;
}
//求2到n的mobius值
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int miu[1000005];
int v[1000005];
int n;

int main(){
    scanf("%d", &n);
    for(int i = 2; i <= n; i++) miu[i] = 1, v[i] = 0;
    for(int i = 2; i <= n; i++){
        if(v[i]) continue;
        miu[i] = -1;
        for(int j = 2*i; j <= n; j += i){
            v[j] = 1;
            if( (j / i) % i == 0 ) miu[j] = 0;
            else miu[j] *= -1;
        }
    }
    for(int i = 2; i <= n; i++){
        printf("%d ", miu[i]);
    }
return 0;
}

9. 51nod 1106

质数检测, 水题

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int n, t;

bool is_prime(int x){
    for(int i = 2; i <= sqrt(x); i++){
        if(x % i == 0){
            return false;
        }
    }
    return true;
}

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &t);
        if(is_prime(t))
            printf("Yes\n");
        else printf("No\n");
    }
return 0;
}

10. 51nod 1012

lcm 算了还是不一个一个做了,这种水题。。。还是二分一下适合我的题。

#include <iostream>
#include <cstdio>
#include <cmath>
#define LL long long

using namespace std;

LL gcd(LL a, LL b){
    return b ? gcd(b, a%b) : a;
}



int main(){
    LL a, b;
    scanf("%lld %lld", &a, &b);
    printf("%lld\n", a/gcd(a ,b)*b);
return 0;
}

11. 51nod 1186

Miller_Robbin 素性检测

为避免C++的高精度,用python编写

import random

def rand(l, r):
    return int((r - l + 1) * random.random() + l)

def qpow(a, x, P):
    ret = 1
    while(x):
        if(x & 1):
            ret = ret * a % P
        a = a * a % P
        x >>= 1
    return ret

def witness(a, n):
    t = 0
    u = n - 1;
    while(not(u & 1)):
        t += 1
        u >>= 1
    last = qpow(a, u, n)
    for i in range(0, t):
        cur = last * last % n
        if(cur == 1 and last != 1 and last != n - 1):
            return 1
        last = cur
    return (last != 1)

def miller_rabin(n, s):
    if(n == 2):
        return 1
    for i in range(0, s):
        a = rand(2, n - 1)
        if witness(a, n):
            return 0
        return 1

n = int(input())

if(miller_rabin(n, 20)):
    print("Yes")
else:
    print("No")

猜你喜欢

转载自blog.csdn.net/yczhaoxun/article/details/81842034