//判断是否是素数
bool is_prime(int num)
{
    if (num < 2)
        return false;
    for (int i = 0; i <= num / i; i++)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

//判断素数的个数
vector<bool>status;
int cnt;
vector<int>prime;
void cnt_prime(int num)
{
    prime.resize(num + 1, true);
    prime[0] = prime[1] = false;
    for (int i = 2; i <= num; i++)
    {
        if (status[i])
        {
            cnt++;
            prime.push_back(i);
            for (int j = 0; j < prime.size() && prime[j] <= num / i; j++)
            {
                status[prime[j] * i] = false;
                if (i % prime[j] == 0)
                    break;
            }
        }
    }
}

//分解质因数
vector<int>ans;
void prime_divide(int num)
{
    for (int i = 2; i <= num; i++)
    {
        if (num % i == 0)
        {
            ans.push_back(i);
            while (num % i == 0)
            {
                num /= i;
            }
        }
    }
    if (num > 1)
        ans.push_back(num);
}

//分解因数
vector<int>ans;
void get_divisors(int num)
{
    for (int i = 1; i <= num / i; i++)
    {
        if (num % i == 0)
        {
            ans.push_back(i);
            if (i != num / i)
                ans.push_back(num / i);
        }
    }
}

//计算因数个数
unordered_map<int, int>all;
int cnt;
typedef long long ll;
const int mod = 1e9 + 7;
ll count(int num)
{
    for (int i = 2; i <= num / i; i++)
    {
        if (num % i == 0)
        {
            while (num % i == 0)
            {
                all[i]++;
                cnt++;
            }
        }
    }
    if (num > 1)
        all[num]++;
    ll result = 0;
    for (auto i : all)
    {
        result = result * (i.second + 1) % mod;
    }
    return result;
}

//计算因数之和
unordered_map<int, int>all;
int cnt;
typedef long long ll;
const int mod = 1e9 + 7;
ll sum(int num)
{
    for (int i = 2; i <= num / i; i++)
    {
        if (num % i == 0)
        {
            while (num % i == 0)
            {
                all[i]++;
                cnt++;
            }
        }
    }
    if (num > 1)
        all[num]++;
    ll result = 0;
    for (auto cnt : all)
    {
        int p = cnt.first;
        int a = cnt.second;
        ll t = 1;
        for (int i = 0; i < a; i++)
        {
            t = (t * p + 1) % mod;
        }
        result = result * t % mod;
    }
    return result;
}

//欧拉函数,即计算小于n有多少数和n互质
int Euler(int num)
{
    int ans = 0;
    for (int i = 2; i <= num / i; i++)
    {
        if (num % i == 0)
        {
            ans = ans / i * (i - 1); //对应公式ans*(1-1/i)
            while (num % i == 0)
                num /= i;
        }
    }
    if (num > 1)
        ans = ans / num * (num - 1);
    return ans;
}

//线性筛求欧拉函数,即求范围内每个数的欧拉函数值

vector<int>phi;
vector<int>prime;
vector<bool>is_prime;
typedef long long ll;
ll Euler(int num)
{
    phi.resize(num + 1, 1);
    is_prime.resize(num + 1, true);
    for (int i = 2; i <= num; i++)
    {
        if (is_prime[i])
        {
            prime.push_back(i);
            phi[i] = i - 1;
        }
        for (int j = 0; j < prime.size() && prime[j] <= num / i; j++)
        {
            is_prime[prime[j] * i] = false;
            if (i % prime[j] == 0)
            {
                phi[prime[j] * i] = prime[j] * phi[i];
                break;
            }
            phi[prime[j] * i] = (prime[j] - 1) * phi[i];
        }
    }
    ll ans = 0;
    for (auto curr : phi)
        ans += curr;
    return ans-1; //不要index=0
}

//求逆元

//逆元的充要条件是am互质,如果m是质数,则可以用ksp求,否则只能用exgcd求

typedef long long ll;
ll ksp(ll n, ll p, ll mod)
{
    ll ans = 1;
    while (p)
    {
        if (p & 1)
            ans = ans * n % mod;
        p >>= 1;
        n = n * n % mod;
    }
    return ans % mod;
}
ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        ll n, p;
        cin >> n >> p;
        if (gcd(n, p) != 1)
            cout << "impossible" << endl;
        else
            cout << ksp(n, p - 2, p)<<endl;
    }
}

//扩展欧几里得

例题:求线性同余方程

typedef long long ll;
int exgcd(int a, int b, int& x, int& y)
{
    if (b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int a, b, m;
        cin >> a >> b >> m;
        int x, y = 0;
        int d = exgcd(a, m, x, y);
        if (b % d)
            cout << "impossible" << endl;
        else
            cout << (ll)x * (b / d) % m << endl;;
    }
    return 0;
}

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐