洛谷题单指南-进阶数论-P4139 上帝与集合的正确用法

原题链接:https://www.luogu.com.cn/problem/P4139

题意解读:给多组p,求

image

解题思路:

设b = image,即要求2b % p

b无限大,显然b > Φ(p),根据扩展欧拉定理可以将上式转换为2b % Φ(p) + Φ(p) % p

设f(p) = 2b % p = 2b % Φ(p) + Φ(p) % p

进一步转化:f(p) = 2f(Φ(p)) + Φ(p) % p

设ksm(a, b, p)为计算ab % p的快速幂函数,可以得到如下递归定义:

  • 当p != 1时,f(p) = ksm(2, f(Φ(p)) + Φ(p), p)
  • 当p == 1时,f(p) = 0

Φ(p)的值提前用欧拉筛将1~10000000的欧拉函数phi[i]预处理出来即可。

100分代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int N = 10000005;
LL phi[N], primes[N], cnt;
bool vis[N];
LL T, p;

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

void euler()
{
    for(LL i = 1; i < N; i++) phi[i] = i;
    for(LL i = 2; i < N; i++)
    {
        if(!vis[i])
        {
            phi[i] = i - 1;
            primes[++cnt] = i;
            vis[i] = true;
        }
        for(int j = 1; j <= cnt; j++)
        {
            if(i * primes[j] >= N) break;
            vis[i * primes[j]] = true;
            if(i % primes[j] == 0)
            {
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            else
            {
                phi[i * primes[j]] = phi[i] * (primes[j] - 1);
            }
        }
    }
}

LL f(LL p)
{
    if(p == 1) return 0;
    return ksm(2, f(phi[p]) + phi[p], p);
}

int main()
{
    euler();
    cin >> T;
    while(T--)
    {
        cin >> p;
        cout << f(p) << endl;
    }
    return 0;
}

 

posted @ 2025-11-05 10:37  hackerchef  阅读(7)  评论(0)    收藏  举报