結果
| 問題 |
No.1618 Convolution?
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-03-14 15:08:55 |
| 言語 | Go (1.23.4) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,602 bytes |
| コンパイル時間 | 12,010 ms |
| コンパイル使用メモリ | 230,308 KB |
| 実行使用メモリ | 71,024 KB |
| 最終ジャッジ日時 | 2024-09-18 08:04:53 |
| 合計ジャッジ時間 | 28,160 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 3 WA * 12 |
ソースコード
package main
import (
"bufio"
"fmt"
"math"
"math/bits"
"os"
)
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n int
fmt.Fscan(in, &n)
A := make([]int, n)
for i := 0; i < n; i++ {
fmt.Fscan(in, &A[i])
}
B := make([]int, n)
for i := 0; i < n; i++ {
fmt.Fscan(in, &B[i])
}
A = append([]int{0}, A...)
B = append([]int{0}, B...)
f := make([]int, n+1) // 0-n
for i := range f {
f[i] = i
}
A = Convolution(A, f) // ∑i*A[i]
B = Convolution(B, f) // ∑j*B[j]
for i := range B {
A[i] += B[i]
}
A = A[1:]
for _, v := range A {
fmt.Fprint(out, v, " ")
}
}
// 计算 A(x) 和 B(x) 的卷积
// c[i] = ∑a[k]*b[i-k], k=0..i
// 入参出参都是次项从低到高的系数
func Convolution(a, b []int) []int {
n, m := len(a), len(b)
limit := 1 << uint(bits.Len(uint(n+m-1)))
f := newFFT(limit)
cmplxA := make([]complex128, limit)
for i, v := range a {
cmplxA[i] = complex(float64(v), 0)
}
cmplxB := make([]complex128, limit)
for i, v := range b {
cmplxB[i] = complex(float64(v), 0)
}
f.dft(cmplxA)
f.dft(cmplxB)
for i := range cmplxA {
cmplxA[i] *= cmplxB[i]
}
f.idft(cmplxA)
conv := make([]int, n+m-1)
for i := range conv {
conv[i] = int(math.Round(real(cmplxA[i])))
}
return conv
}
// 计算多个多项式的卷积
// 入参出参都是次项从低到高的系数
func MultiConvolution(coefs [][]int) []int {
n := len(coefs)
if n == 1 {
return coefs[0]
}
return Convolution(MultiConvolution(coefs[:n/2]), MultiConvolution(coefs[n/2:]))
}
// https://github.dev/EndlessCheng/codeforces-go/tree/master/copypasta
type fft struct {
n int
omega, omegaInv []complex128
}
func newFFT(n int) *fft {
omega := make([]complex128, n)
omegaInv := make([]complex128, n)
for i := range omega {
sin, cos := math.Sincos(2 * math.Pi * float64(i) / float64(n))
omega[i] = complex(cos, sin)
omegaInv[i] = complex(cos, -sin)
}
return &fft{n, omega, omegaInv}
}
func (f *fft) transform(a, omega []complex128) {
for i, j := 0, 0; i < f.n; i++ {
if i > j {
a[i], a[j] = a[j], a[i]
}
for l := f.n >> 1; ; l >>= 1 {
j ^= l
if j >= l {
break
}
}
}
for l := 2; l <= f.n; l <<= 1 {
m := l >> 1
for st := 0; st < f.n; st += l {
p := a[st:]
for i := 0; i < m; i++ {
t := omega[f.n/l*i] * p[m+i]
p[m+i] = p[i] - t
p[i] += t
}
}
}
}
func (f *fft) dft(a []complex128) {
f.transform(a, f.omega)
}
func (f *fft) idft(a []complex128) {
f.transform(a, f.omegaInv)
for i := range a {
a[i] /= complex(float64(f.n), 0)
}
}