こんにちは、ナナオです。

前回に引き続き競プロを実施していきたいと思います。

今回の問題は以下です。

総和の計算 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】

実装

シンプルに実装するとこうです。

package main
import "fmt"
func main(){
    var a, b int
    fmt.Scan(&a, &b)
    r := 0
    for i := a; i <= b; i++ {
        r += i
    }
    fmt.Println(r)
}

ですがこれだと実行時間制約に間に合いません。

ということで解説を見ます。

1 - Nまでの総和はN(N + 1) / 2で求めることができるようです。

ということでAからBまでの総和は(1からBまでの総和) - (1からA - 1までの総和)ということになります。

この法則に従って実装を修正します。

package main
import "fmt"
func main(){
    var a, b uint64
    fmt.Scan(&a, &b)
    r := ((b * (b + 1)) / 2) - ((a * (a - 1)) / 2)
    fmt.Println(r)
}

と、修正しましたが、うまく値が出力されません。

どうやらこの問題の解答の最大値がGoだとオーバーフローしてしまうようです。

AIと壁打ちしたところ、math/bigパッケージを使えば解決するようです。

package main
import (
    "fmt"
    "math/big"
)
func main(){
    a := new(big.Int)
    b := new(big.Int)
    fmt.Scan(a, b)
    one := big.NewInt(1)
    two := big.NewInt(2)
    
    // b * (b + 1) / 2
    t1 := new(big.Int).Div(new(big.Int).Mul(b, new(big.Int).Add(b, one)), two)
    // a * (a - 1) / 2
    t2 := new(big.Int).Div(new(big.Int).Mul(a, new(big.Int).Sub(a, one)), two)
    r := new(big.Int).Sub(t1, t2)
    fmt.Println(r.String())
}

相当冗長なコードになりました。が、まぁ一応解決したのでいいでしょう。

ということで今回はこれで👍