社区讨论
WA85求调
P15343「RedStone OI R1 C」Super Fib参与者 6已保存回复 16
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 16 条
- 当前快照
- 1 份
- 快照标识符
- @mlnuu5ht
- 此快照首次捕获于
- 2026/02/15 22:42 4 天前
- 此快照最后确认于
- 2026/02/16 19:08 3 天前
挂且仅挂了 Sub3 所有点是何意味啊。。。。。。
CPP#include <stdio.h>
#include <immintrin.h>
#pragma GCC target("avx2")
typedef __m256i m256i;
typedef unsigned uint;
typedef unsigned long long ull;
uint P, Pinv, R, R2;
inline
void init() {
uint x = P & 1;
x *= 2u - P * x;
x *= 2u - P * x;
x *= 2u - P * x;
x *= 2u - P * x;
x *= 2u - P * x;
Pinv = -x;
R = (1llu << 32) % P, R2 = (ull)R * R % P;
}
inline uint redc(ull t) { return (t + ull((uint)t * Pinv) * P) >> 32; }
inline uint mul(uint x, uint y) { return redc((ull)x * y); }
inline uint toMont(uint x) { return mul(x, R2); }
inline uint fromMont(uint x) { return x = redc(x), x < P ? x : x - P; }
inline uint add(uint x, uint y) { return x += y, x >= P ? x - P : x; }
inline uint sub(uint x, uint y) { return x < y ? x + P - y : x - y; }
inline
m256i add(m256i x, m256i y) {
m256i s = _mm256_add_epi32(x, y);
m256i d = _mm256_sub_epi32(s, _mm256_set1_epi32(P));
return _mm256_min_epu32(s, d);
}
inline
m256i redc(m256i x) {
m256i m = _mm256_mul_epu32(x, _mm256_set1_epi32(Pinv));
m256i v = _mm256_mul_epu32(m, _mm256_set1_epi32(P));
return _mm256_add_epi64(x, v);
}
inline
m256i mul(m256i x, m256i y) {
m256i x1 = _mm256_shuffle_epi32(x, 0xF5);
m256i y1 = _mm256_shuffle_epi32(y, 0xF5);
m256i res0 = redc(_mm256_mul_epu32(x, y));
m256i res1 = redc(_mm256_mul_epu32(x1, y1));
res0 = _mm256_shuffle_epi32(res0, 0xF5);
return _mm256_blend_epi32(res0, res1, 0xAA);
}
typedef m256i vec;
inline
void sqr_mat(const auto __restrict__ a, auto __restrict__ res) {
for (int i = 0; i < 8; i++) *(m256i *)res[i] = _mm256_set1_epi32(0);
for (int i = 0; i < 8; i++) {
for (int k = 0; k < 8; k++) {
if (a[i][k]) *(m256i *)res[i] = add(mul(_mm256_set1_epi32(a[i][k]), *(m256i *)a[k]), *(m256i *)res[i]);
}
}
}
inline
void mul_vec(const uint* __restrict__ a, const auto __restrict__ b, uint* __restrict__ res) {
*(m256i *)res = _mm256_set1_epi32(0);
for (int k = 0; k < 8; k++) {
if (a[k]) *(m256i *)res = add(mul(_mm256_set1_epi32(a[k]), *(m256i *)b[k]), *(m256i *)res);
}
}
alignas(32) uint f[8][8], g[8][8], res[8], tmp[8];
inline
void qpow(ull n) {
for (; ; ) {
if (n & 1) mul_vec(res, f, tmp), *(m256i *)res = *(m256i *)tmp;
n >>= 1; if (!n) break; sqr_mat(f, g);
for (int j = 0; j < 8; j++) *(m256i *)f[j] = *(m256i *)g[j];
}
}
int T; uint a, b, c, p, q; ull n;
int main() {
for (scanf("%d", &T); T--; ) {
scanf("%u%u%u%u%u%llu%u", &a, &b, &c, &p, &q, &n, &P), init();
a %= P, b %= P, c %= P, p %= P, q %= P;
*(m256i *)res = _mm256_set_epi32(0, 0, toMont(1 % P), toMont(1 % P), toMont(1 % P), toMont(c), toMont(b), toMont(a));
ull nx = (n - 1) / 3, ny = n % 3;
if (nx) {
uint i1 = toMont(1 % P), i3 = toMont(3 % P), i6 = toMont(6 % P), i7 = toMont(7 % P), i9 = toMont(9 % P);
uint i11 = toMont(11 % P), i12 = toMont(12 % P), i20 = toMont(20 % P), i30 = toMont(30 % P);
p = toMont(p), q = toMont(q);
uint p2 = mul(p, p), x = add(p2, q), y = add(mul(i7, p), i9), z = add(p, i1), w = add(mul(i12, p), i20);
uint tx = mul(p, x), ty = add(mul(p, y), i11), tz = add(mul(p, z), i1), tw = add(mul(p, w), i30);
*(m256i *)f[0] = _mm256_set_epi32(0, i1, 0, 0, 0, mul(p2, q), mul(p, q), q);
*(m256i *)f[1] = _mm256_set_epi32(0, i1, 0, 0, 0, q, 0, 0);
*(m256i *)f[2] = _mm256_set_epi32(0, i1, 0, 0, 0, tx, x, p);
*(m256i *)f[3] = _mm256_set_epi32(0, 0, 0, i6, i1, ty, y, i7);
*(m256i *)f[4] = _mm256_set_epi32(0, 0, 0, i1, 0, tz, z, i1);
*(m256i *)f[5] = _mm256_set_epi32(0, 0, i1, i9, i3, tw, w, i12);
*(m256i *)f[6] = _mm256_set_epi32(0, i1, 0, 0, 0, 0, 0, 0);
*(m256i *)f[7] = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0);
qpow(nx);
}
uint ans = add(res[0], res[6]);
if (~ny & 1) ans = add(ans, res[1]);
if (!ny) ans = add(ans, res[2]);
printf("%u\n", fromMont(ans));
}
}
回复
共 16 条回复,欢迎继续交流。
正在加载回复...