这类 RE 一般情况下是什么问题,或者能不能找出代码中为何会出发SIGILL。
#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
namespace IO {
const int SIZ = 1 << 14;
inline char getc() {
static char bf[SIZ], *begin = bf, *end = bf;
if (begin == end) begin = bf, end = bf + fread(bf, 1, SIZ, stdin);
if (begin == end) return EOF;
return *begin++;
}
char wbf[SIZ], *wend = wbf, *weoo = wbf + SIZ;
inline void putc(char c) {
*wend = c, ++wend;
if (wend == weoo) fwrite(wbf, 1, SIZ, stdout), wend = wbf;
}
inline void do_flush() { fwrite(wbf, 1, wend - wbf, stdout); }
template <typename T>
inline void uread(T &ans) {
static char tmp;
tmp = getc(), ans = 0;
while (!isdigit(tmp)) tmp = getc();
while (isdigit(tmp)) ans = (ans << 1) + (ans << 3) + (tmp ^ 48), tmp = getc();
}
template <typename T>
inline void read(T &ans) {
static char tmp2;
static bool flag;
tmp2 = getc(), ans = 0, flag = 0;
while (!isdigit(tmp2)) {
if (tmp2 == '-') flag = 1;
tmp2 = getc();
}
while (isdigit(tmp2)) ans = (ans << 1) + (ans << 3) + (tmp2 ^ 48), tmp2 = getc();
if (flag) ans = -ans;
}
template <typename T>
inline void uwrite(T x) {
if (x > 9) uwrite(x / 10);
putc(x % 10 + '0');
}
template <typename T>
inline void write(T x) {
if (x < 0)
putc('-'), uwrite(-x);
else
uwrite(x);
}
}; // namespace IO
using IO::read;
using IO::write;
using IO::do_flush;
const int N = 2e6 + 10;
int id1[N], id2[N];
__int128 n, k;
inline int id(__int128 x) { return x < N ? id1[x] : id2[n / x]; }
__int128 prime[N];
int cnt, vcnt;
__int128 v[N], g[N];
bool vis[N];
void init(int n) {
vis[1] = 1;
for (int i = 1; i <= n; i++) {
if (!vis[i]) prime[++cnt] = i;
for (int j = 1; j <= cnt && i * prime[j] <= n; j++) {
vis[i * prime[j]] = 1;
if (!(i % prime[j])) break;
}
}
}
void sieve(__int128 n) {
// memset(g, 0, sizeof(g));
vcnt = 0;
for (__int128 l = 1, r; l <= n; l = r + 1) {
r = n / (n / l), v[++vcnt] = n / l;
if (v[vcnt] < N)
id1[v[vcnt]] = vcnt;
else
id2[n / v[vcnt]] = vcnt;
g[vcnt] = v[vcnt] - 1;
}
for (int i = 1; i <= cnt && prime[i] * prime[i] <= n; i++)
for (int j = 1; j <= vcnt && prime[i] <= v[j] / prime[i]; j++) g[j] = g[j] - (g[id(v[j] / prime[i])] - g[id(prime[i - 1])]);
}
int T;
inline __int128 calc(__int128 a, __int128 b) {
__int128 ans = 0;
while (a) ans += a / b, a /= b;
return (ans + 1) % k;
}
inline __int128 qpw(__int128 a, long long b) {
__int128 ans = 1;
while (b) {
if (b & 1) ans = ans * a % k;
a = a * a % k, b >>= 1;
}
return ans;
}
inline __int128 sqrtt(__int128 a) {
__int128 ans = 0, mid, l = 1, r = a;
while (l <= r) {
mid = (l + r) / 2;
if (mid * mid <= a)
ans = mid, l = mid + 1;
else
r = mid - 1;
}
return ans;
}
signed main() {
read(T);
init(2000000);
// init(sqrt(n) + 1);
for (int i = 1; i <= T; i++) {
read(n), read(k);
sieve(n);
__int128 ans = 1;
__int128 tmp = n / (__int128)(sqrtt(n));
// cout << "tmp:" << (long long)tmp << endl;
for (int i = 1; prime[i] <= tmp; i++) ans = ans * calc(n, prime[i]) % k;
for (__int128 l = tmp + 1, r; l <= n; l = r + 1) r = n / (n / l), ans = ans * qpw(n / l + 1, g[id(r)] - g[id(l - 1)]) % k;
write(ans), IO::putc('\n');
}
do_flush();
return 0;
}