public static void CalculateInv(Span <StaticModInt <T> > a) { var n = a.Length; var h = InternalMath.CeilPow2(n); for (int ph = h; ph >= 1; ph--) { // ブロックサイズの半分 int w = 1 << (ph - 1); // ブロック数 int p = 1 << (h - ph); var iNow = StaticModInt <T> .Raw(1); // 各ブロックの s 段目 for (int s = 0; s < w; s++) { int offset = s << (h - ph + 1); for (int i = 0; i < p; i++) { var l = a[i + offset]; var r = a[i + offset + p]; a[i + offset] = l + r; a[i + offset + p] = StaticModInt <T> .Raw( unchecked ((int)((ulong)(default(T).Mod + l.Value - r.Value) * (ulong)iNow.Value % default(T).Mod))); } iNow *= sumIE[InternalBit.BSF(~(uint)s)]; } } }
public static void Calculate(Span <StaticModInt <T> > a) { var n = a.Length; var h = InternalMath.CeilPow2(n); for (int ph = 1; ph <= h; ph++) { // ブロックサイズの半分 int w = 1 << (ph - 1); // ブロック数 int p = 1 << (h - ph); var now = StaticModInt <T> .Raw(1); // 各ブロックの s 段目 for (int s = 0; s < w; s++) { int offset = s << (h - ph + 1); for (int i = 0; i < p; i++) { var l = a[i + offset]; var r = a[i + offset + p] * now; a[i + offset] = l + r; a[i + offset + p] = l - r; } now *= sumE[InternalBit.BSF(~(uint)s)]; } } }