洛谷题单指南-进阶数论-P4139 上帝与集合的正确用法
原题链接:https://www.luogu.com.cn/problem/P4139
题意解读:给多组p,求
![]()
解题思路:
设b =
,即要求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;
}
浙公网安备 33010602011771号