80pts求调
查看原帖
80pts求调
731608
TeraniRetZiger楼主2022/6/23 16:58

rt。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef __int128 lll;

const int MAXN = 4.7e6;
const int MAXM = 1e5 + 10;

int mod;

int p[MAXN], tot;
ll phi[MAXN];

bool vis[MAXN];

inline 
void init(ll n) {
	phi[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!vis[i]) p[++tot] = i, phi[i] = i - 1;
		for (int j = 1; j <= tot; j++) {
			if (i * p[j] > n) break;
			vis[i * p[j]] = 1;
			if (i % p[j] == 0) { phi[i * p[j]] = phi[i] * p[j] % mod; break; }
			phi[i * p[j]] = phi[i] * (p[j] - 1) % mod;
		}
	}
	for (int i = 1; i <= n; i++) phi[i] = (phi[i - 1] + (ll)i * i % mod * phi[i]) % mod;
}

inline 
ll sum(ll n) {
	return n %= mod, (n * (n + 1) >> 1) % mod;
}

inline 
ll sumfg(ll n) {
	ll t = sum(n);
	return t * t % mod;
}

inline 
ll sumg(ll n) {
	return n * (n + 1) * (n << 1 | 1) / 6 % mod;
}

ll t1[MAXM], t2[MAXM];

ll n;

int lim, k;

inline 
ll add(ll p, ll x) {
	return p <= k ? t1[p] = x : t2[n / p] = x;
}

inline 
ll get(ll p) {
	return p <= k ? t1[p] : t2[n / p];
}

inline 
ll sumf(ll x) {
	if (x <= lim) return phi[x];
	if (get(x)) return get(x);
	ll res = sumfg(x);
	for (ll l = 2, r; l <= x; l = r + 1) {
		r = x / (x / l);
		res = (res - (sumg(r) - sumg(l - 1) + mod) % mod * sumf(x / l) % mod + mod) % mod;
	}
	return add(x, res);
}

ll res;

int main() {
	scanf("%d%lld", &mod, &n);
	k = sqrt(n), lim = cbrt(n);
	lim *= lim;
	init(lim);
	for (ll l = 1, r; l <= n; l = r + 1) {
		r = n / (n / l);
		res = (res + (sumf(r) - sumf(l - 1) + mod) % mod * sumfg(n / l)) % mod;
	}
	printf("%lld", res);
}
2022/6/23 16:58
加载中...