题目描述
组数据,对于每组数据,给定 ,计算下面的式子对 取余的结果。
其中 。
推一下式子:
利用 :
把枚举 提到前面,原先的枚举 就变成了枚举 的倍数 。
设 :
平方里面是个等比数列求和,可以在 的时间复杂度内解决,至于 ,可以在每枚举到一个 的时候快速幂一下 ,然后在枚举 一步一步乘。
枚举 是调和级数 ,后面复杂度就不会分析了,有大佬证明出是 的。
如何在 的时间内算 项等比数列的和?
设 为等比数列的前 项和,那么有:
实际上就是在分治快速幂算 的时候顺带算了一下 ,注意到在算 的时候把 算出来后传给上一层,这样复杂度就为 了,不必再快速幂计算 。
#include<iostream>
#include<cstdio>
#include<algorithm>
namespace do_while_true {
#define ld double
#define ll long long
#define re register
#define pb push_back
#define fir first
#define sec second
#define pp std::pair<ll, ll>
#define mp std::make_pair
template <typename T>
inline T Max(T x, T y) { return x > y ? x : y; }
template <typename T>
inline T Min(T x, T y) { return x < y ? x : y; }
template <typename T>
inline T Abs(T x) { return x < 0 ? -x : x; }
template <typename T>
inline T& read(T& r) {
r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
return r = w ? -r : r;
}
template <typename T>
inline T qpow(T x, T y, T mod) {
re T sumq = 1; x %= mod;
while(y) {
if(y&1) sumq = sumq * x % mod;
x = x * x % mod;
y >>= 1;
}
return sumq;
}
char outch[110];
int outct;
template <typename T>
inline void print(T x) {
do {
outch[++outct] = x % 10 + '0';
x /= 10;
} while(x);
while(outct >= 1) putchar(outch[outct--]);
}
}
using namespace do_while_true;
const int N = 1500010 + 10;
template <typename T, typename T2>
inline T Mod(T x, T2 p) { return x % p; }
ll ans;
bool vis[N];
int prime[N], ct, mu[N];
pp db(ll x, int n, ll p) {
if(n == 0) return mp(1ll, 1ll);
if(n == 1) return mp(x, x);
if((n & 1) == 0) {
pp temp = db(x, n / 2, p);
return mp(temp.fir * ((1 + temp.sec) % p) % p, temp.sec * temp.sec % p);
}
pp temp = db(x, (n-1) / 2, p);
ll qn = temp.sec * temp.sec % p * x % p;
return mp((temp.fir * ((1 + temp.sec) % p) % p + qn) % p, qn);
}
void mian(int n, ll p) {
ans = 0;
for(int d = 1; d <= n; ++d) {
ll dd = qpow(1ll * d, 1ll * d, p);
ll kd = dd;
for(int k = 1; k <= n / d; ++k) {
pp temp = db(kd, n / (k * d), p);
ans = (ans + temp.fir * temp.fir % p * Mod(mu[k] + p, p) % p) % p;
kd = kd * dd % p;
}
}
printf("%lld\n", ans);
}
int n[3], mx;
ll p[3];
void pre() {
vis[1] = 1; mu[1] = 1;
for(int i = 2; i <= mx; ++i) {
if(!vis[i]) {
prime[++ct] = i;
mu[i] = -1;
}
for(int j = 1; j <= ct && 1ll * i * prime[j] <= mx; ++j) {
vis[i * prime[j]] = 1;
if(i % prime[j] == 0) {
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = mu[i] * mu[prime[j]];
}
}
}
signed main() {
int T = 1;
read(T);
for(int i = 1; i <= T; ++i) read(n[i]), read(p[i]), mx = Max(mx, n[i]);
pre();
for(int i = 1; i <= T; ++i) mian(n[i], p[i]);
fclose(stdin);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?