这道题目简化来看就是求3到n+1的所有数和3到n+1的所有质数和,不知道min25筛会很难算,虽然也有打表过去的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int maxn = 1e6 + 10;
bool valid[maxn];
ll prime[maxn];
ll sum[maxn];
int tot;
void init()
{
tot = 0;
valid[1] = true;
for(int i = 2; i < maxn; i++)
{
if(!valid[i])
{
prime[++tot] = i;
sum[tot] = sum[tot - 1] + ll(i);
}
for(int j = 1; j <= tot && i * prime[j] < maxn; j++)
{
valid[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
ll id1[maxn], id2[maxn];
ll w[maxn], g[maxn];
ll solve(ll n, ll md)
{
ll sqr = sqrt(n + 0.5);
//init(sqr);
int ntot = 0;
for(ll i = 1; i <= tot; i++)
{
if(prime[i] <= sqr) ntot++;
else break;
}
int m = 0;
for(ll i = 1; i <= n; i = n / (n / i) + 1)
{
w[++m] = n / i;
if(w[m] <= sqr) id1[w[m]] = m;
else id2[n/ w[m]] = m;
g[m] = w[m] * (w[m] + ll(1));
g[m] /= ll(2);
g[m]--;
}
for(int j = 1; j <= ntot; j++)
{
for(int i = 1; i <= m && (ll)prime[j] * (ll)prime[j] <= w[i]; i++)
{
ll k = (w[i] / prime[j] <= sqr) ? id1[w[i] / prime[j]] : id2[n / (w[i] / prime[j])];
g[i] = g[i] - prime[j] * (g[k] - sum[j - 1]);
}
}
return g[id2[1]];
}
int main()
{
init();
int t;
scanf("%d", &t);
while(t--)
{
ll n, md;
scanf("%lld%lld", &n, &md);
if(n == 1)
{
printf("0\n");
continue;
}
n++;
ll ans = (n % md) * ((n + 1)% md);
if(ans & 1) ans += md;
ans /= ll(2);
ans %= md;
ans -= 5;
ans = (ans + md) % md;
ans += solve(n, md) % md;
ans %= md;
printf("%lld\n", ans);
}
return 0;
}
/*
1000
10000000000 998244353
*/