hdu 4910 Problem about GCD(数论)

题目连接:hdu 4910 Problem about GCD

题目大意:给定M,判断所有小于M并且和M互质的数的积取模M的值。

解题思路:有个数论的结论,若为偶数,M=M/2. 可以写成M=pk,即只有一种质因子时,答案为M-1,否则为1.特殊情况为4的倍数,不包括4.

首先用1e6以内的素数去试除,如果都不可以为p,那么对大于1e6的情况判断一下是否为素数,是素数也可以(k=1),否则开方计算,因为M最大为1e18,不可能包含3个大于1e6的质因子。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime> // possible need;
#include <cstdlib> // possible need;
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long type;
type mul_mod (type a, type b, type mod) {
    type ret = 0;
    while (b) {
        if (b&1)
            ret = (ret + a) % mod;
        a = (a + a) % mod;
        b >>= 1;
    }
    return ret;
}

type pow_mod (type a, type n, type mod) {
    type ans = 1;
    while (n) {
        if (n&1)
            ans = mul_mod(ans, a, mod);
        a = mul_mod(a, a, mod);
        n >>= 1;
    }
    return ans;
}

bool miller_rabin(type n) {
    if (n < 2)
        return false;

    srand(time(0));
    for (int i = 0; i < 20; i++)
        if (pow_mod(rand() % (n-1) + 1, n-1, n) != 1)
            return false;
    return true;
}

typedef long long ll;
const int maxn = 1e6;

bool vis[maxn+5];
int np, pri[maxn+5];

void prime_table (int n) {
    np = 0;
    memset(vis, 0, sizeof(vis));

    for (int i = 3; i <= n; i += 2) {
        if (vis[i])
            continue;
        pri[np++] = i;
        for (int j = i * 2; j <= n; j += i)
            vis[j] = 1;
    }
}

bool judge (ll M) {
    if (M % 2 == 0)
        M /= 2;

    for (int i = 0; i < np; i++) {
        ll tmp = M;
        while (tmp % pri[i] == 0)
            tmp /= pri[i];
        if (tmp == 1)
            return true;
    }

    if (M <= 1000000LL)
        return false;

    if (miller_rabin(M))
        return true;

    ll x = sqrt(M+0.0);
    while (x * x < M)
        x++;

    if (x * x != M)
        return false;

    if (miller_rabin(x))
        return true;
    return false;
}

int main () {
    ll M;
    prime_table(maxn);

    //srand(time(0));
    while (scanf("%I64d", &M) == 1 && M != -1) {
        if (M == 1 || M == 2 || M == 4 || judge(M))
            printf("%I64d\n", M-1);
        else
            printf("1\n");
    }
    return 0;
}

hdu 4910 Problem about GCD(数论),布布扣,bubuko.com

时间: 2024-08-04 22:28:04

hdu 4910 Problem about GCD(数论)的相关文章

HDU 4910 Problem about GCD

Problem about GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 470    Accepted Submission(s): 77 Problem Description Given integer m. Find multiplication of all 1<=a<=m such gcd(a, m)=1 (cop

HDU 4910 Problem about GCD(米勒拉宾)

HDU 4910 Problem about GCD 题目链接 题意:给定一个数字,求出1 - n之间与他互质的数的乘积mod n 思路:看了网上别人找出来的规律,原文链接 然后由于这题的n很大,也没法直接判定,可以这样搞,先去试10^6以内的素数,判断可不可以,如果不行,再利用米勒拉宾判下是否是素数,如果不是的话,把这个数字开根在平方,判断是不是完全平方数,这样做的原因是数字最大10^18,如果没有10^6以内的质因子,又不是质数的话,那么他最多只能包含2个质因子了,那么如果他不是一个完全平方

hdu 4983 Goffi and GCD(数论)

题目链接:hdu 4983 Goffi and GCD 题目大意:求有多少对元组满足题目中的公式. 解题思路: n = 1或者k=2时:答案为1 k > 2时:答案为0(n≠1) k = 1时:需要计算,枚举n的因子,令因子k=gcd(n?a,n, 那么另一边的gcd(n?b,n)=nk才能满足相乘等n,满足k=gcd(n?a,n)的a的个数即为?(n/s),欧拉有o(n ̄ ̄√的算法 #include <cstdio> #include <cstring> #include

HDU 2256 Problem of Precision 数论矩阵快速幂

题目要求求出(√2+√3)2n的整数部分再mod 1024. (√2+√3)2n=(5+2√6)n 如果直接计算,用double存值,当n很大的时候,精度损失会变大,无法得到想要的结果. 我们发现(5+2√6)n+(5-2√6)n是一个整数(2√6的偶数次幂总会正负抵消掉),并且(5-2√6)n是小于1的.所以我们就只需要求出Sn-1即可.令 An=(5+2√6)n;  Bn=(5-2√6)n. Sn=An+Bn     Sn为整数. Sn*((5+2√6)+(5-2√6))=Sn*10 Sn*

HDU 4910 HDOJ Problem about GCD BestCoder #3 第四题

首先 m = 1 时 ans = 0对于 m > 1 的 情况 由于 1 到 m-1 中所有和m互质的数字,在 对m的乘法取模 运算上形成了群 ai = ( 1<=a<m && gcd(a,m) == 1 ) 所以 对于 a 必然存在b = a^(-1) = inv(a) 使得 a * b = 1 (mod m) 这里存在两种情况 a != b 那么最后的连乘式中a b均出现一次,相乘得1 a == b 那么最后的连乘式中只出现一个a 实际上所有 a = inv(a) 的

HDU 4983 Goffi and GCD(数论)

HDU 4983 Goffi and GCD 思路:数论题,如果k为2和n为1,那么只可能1种,其他的k > 2就是0种,那么其实只要考虑k = 1的情况了,k = 1的时候,枚举n的因子,然后等于求该因子满足的个数,那么gcd(x, n) = 该因子的个数为phi(n / 该因子),然后再利用乘法原理计算即可 代码: #include <cstdio> #include <cstring> #include <cmath> typedef long long l

hdu 5869 区间不同GCD个数(树状数组)

Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 58 Problem Description This is a simple problem. The teacher gives Bob a list of probl

hdu 1299 Diophantus of Alexandria (数论)

Diophantus of Alexandria Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2269    Accepted Submission(s): 851 Problem Description Diophantus of Alexandria was an egypt mathematician living in Ale

hdu 4944 FSF’s game(数论)

题目链接:hdu 4944 FSF's game 题目大意:给定N,可以用不大于N的长a和宽b,组成N?(N?1)2种不同的矩形,对于每个矩形a?b要计算它的值,K为矩形a,b可以拆分成若干个K?K的正方形.∑a?bgcd(a/k,b/k),输出所有矩形值的和. 解题思路:假设有边a和b,那么k肯定即使a的因子也是b的因子.定义f(n)为矩形最长边等于n的情况下所有矩形值的和.那么f(n)=val(1?n)+val(2?n)+?+val(n?n),枚举n的因子作为k,现在假设有因子k,使得n=k