static ulong[] InverseFft(ulong[] vector) { var size = vector.Length; if (size == 1) { return(vector); } var evenVector = new ulong[size / 2]; var oddVector = new ulong[size / 2]; for (int i = 0; i < size / 2; i++) { evenVector[i] = vector[2 * i]; oddVector[i] = vector[2 * i + 1]; } evenVector = InverseFft(evenVector); oddVector = InverseFft(oddVector); ulong pow = (ulong)(Power / size); ulong root_n = IntegerMath.ModPow(Root_1, pow, Mod); ulong w = 1; var result = new ulong[size]; for (int i = 0; i < size / 2; i++) { result[i] = (Inverse * (evenVector[i] + (w * oddVector[i]) % Mod) % Mod) % Mod; result[i + size / 2] = (Inverse * (evenVector[i] + Mod - (w * oddVector[i]) % Mod) % Mod) % Mod; w = (root_n * w) % Mod; } return(result); }
static ulong[] SlowInverseFt(ulong[] vector) { var size = vector.Length; var res = new ulong[size]; ulong pow = (ulong)(Power / size); ulong root_n = IntegerMath.ModPow(Root_1, pow, Mod); ulong root_i = 1; for (int i = 0; i < size; i++) { double temp = 0; ulong root_j = 1; for (int j = 0; j < size; j++) { temp = (temp + (vector[j] * root_j) % Mod) % Mod; root_j = (root_j * root_i) % Mod; } res[i] = (ulong)(temp * IntegerMath.Inverse((ulong)size, Mod)) % Mod; root_i = (root_i * root_n) % Mod; } return(res); }