#include <immintrin.h>
#include <stdio.h>
#pragma GCC target("avx2")
#define U unsigned
#define LL long long
#define ULL unsigned long long
#define S static
#define MI __m256i
#define IL inline
#define ADD _mm256_add_epi32
#define SUB _mm256_sub_epi32
#define CMP _mm256_cmpgt_epi32
#define AND _mm256_and_si256
#define MUL _mm256_mul_epu32
#define SRLI1 _mm256_srli_epi64
#define SRLI2 _mm256_srli_si256
#define ADD1 _mm256_add_epi64
#define OR _mm256_or_si256
#define ZERO _mm256_setzero_si256
#define SET _mm256_set_epi32
#define SET1 _mm256_set1_epi32
#define M mon_in
S U mod, r, n2_;
S MI a0, mod1, R, hi32, ans, ml, ad;
LL exgcd(LL a, LL b, LL& x, LL& y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
LL gcd = exgcd(b, a % b, y, x);
y -= a / b * x;
return gcd;
}
U IL mul(U x, U y) {
ULL z = (ULL)x * y;
return (z + (ULL)((U)z * r) * mod) >> 32;
}
IL MI add(MI x, MI y) {
MI apb = ADD(x, y), ret = SUB(apb, mod1);
MI cmp = CMP(a0, ret), add = AND(cmp, mod1);
return ADD(add, ret);
}
IL MI mul(MI x, MI y) {
MI z = x, w, p = y;
y = MUL(x, y);
x = MUL(MUL(y, R), mod1);
w = SRLI1(ADD1(x, y), 32); //
x = SRLI2(z, 4);
y = SRLI2(p, 4);
y = MUL(x, y);
x = MUL(MUL(y, R), mod1);
x = AND(ADD1(x, y), hi32); //
return OR(x, w);
}
IL U mon_in(U x) {
return mul(x, n2_);
}
IL U mon_out(U x) {
U ret = ((x + (ULL)((U)x * r) * mod) >> 32);
return ret < mod ? ret : ret - mod;
}
void solve(int n, int p) {
U i = 1;
LL x, y;
mod = p;
n2_ = -(ULL)mod % mod;
exgcd(mod, 1ll << 32, x, y);
r = -(U)x; //
a0 = ZERO();
mod1 = SET1(mod);
R = SET1(r);
hi32 = SET(-1, 0, -1, 0, -1, 0, -1, 0);
ans = SET1(M(1));
ad = SET1(M(8));
ml = SET(M(8), M(7), M(6), M(5), M(4), M(3), M(2), M(1));
for (; i + 8 <= n; i += 8) {// 这里
ans = mul(ans, ml);
ml = add(ml, ad);
}
U* fl = (U*)&ans;
U as = mul(mul(mul(fl[0], fl[1]), mul(fl[2], fl[3])),
mul(mul(fl[4], fl[5]), mul(fl[6], fl[7])));
as = mon_out(as);
for (; i <= n; ++i)
as = 1ull * as * i % mod;
printf("%u\n", as);
}
main(int T) {
scanf("%d", &T);
while (T--) {
int n, p;
scanf("%d%d", &n, &p);
solve(n, p);
}
}
这里又在题解基础上加了循环展开,只快了 0.03s 崩不住了(求助大佬真难卡