結果

問題 No.2440 Accuracy of Integer Division Approximate Functions
ユーザー 👑 MizarMizar
提出日時 2023-08-21 08:59:59
言語 Go
(1.22.1)
結果
AC  
実行時間 73 ms / 2,000 ms
コード長 1,591 bytes
コンパイル時間 14,739 ms
コンパイル使用メモリ 229,320 KB
実行使用メモリ 6,656 KB
最終ジャッジ日時 2024-06-02 10:00:02
合計ジャッジ時間 14,249 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 71 ms
6,528 KB
testcase_02 AC 71 ms
6,528 KB
testcase_03 AC 71 ms
6,656 KB
testcase_04 AC 71 ms
6,528 KB
testcase_05 AC 72 ms
6,528 KB
testcase_06 AC 53 ms
6,528 KB
testcase_07 AC 53 ms
6,528 KB
testcase_08 AC 53 ms
6,528 KB
testcase_09 AC 53 ms
6,528 KB
testcase_10 AC 52 ms
6,528 KB
testcase_11 AC 73 ms
6,528 KB
testcase_12 AC 73 ms
6,528 KB
testcase_13 AC 73 ms
6,528 KB
testcase_14 AC 71 ms
6,528 KB
testcase_15 AC 72 ms
6,528 KB
testcase_16 AC 37 ms
6,272 KB
testcase_17 AC 37 ms
6,272 KB
testcase_18 AC 39 ms
6,272 KB
testcase_19 AC 38 ms
6,272 KB
testcase_20 AC 39 ms
6,272 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
)

// calc sum_{i=0}^{n-1} floor((ai + b) / m)
func floor_sum_unsigned(ni *big.Int, mi *big.Int, ai *big.Int, bi *big.Int) big.Int {
	n := new(big.Int).Set(ni)
	m := new(big.Int).Set(mi)
	a := new(big.Int).Set(ai)
	b := new(big.Int).Set(bi)
	ans := big.NewInt(0)
	for true {
		if a.Cmp(m) >= 0 {
			var am, t big.Int
			am.DivMod(a, m, a)
			t.Sub(n, big.NewInt(1)).Mul(&t, n).Rsh(&t, 1).Mul(&t, &am)
			ans.Add(ans, &t)
		}
		if b.Cmp(m) >= 0 {
			var bm, t big.Int
			bm.DivMod(b, m, b)
			t.Mul(n, &bm)
			ans.Add(ans, &t)
		}
		var y_max big.Int
		y_max.Mul(a, n)
		y_max.Add(&y_max, b)
		if y_max.Cmp(m) == -1 {
			break
		}
		n.DivMod(&y_max, m, b)
		m, a = a, m
	}
	return *ans
}

func solve(n *big.Int, d *big.Int, m *big.Int, s uint) big.Int {
	var pow2s, dm big.Int
	a := new(big.Int).Set(n)
	pow2s.Lsh(big.NewInt(1), s)
	dm.Mul(new(big.Int).Set(d), new(big.Int).Set(m))
	if pow2s.Cmp(&dm) != 0 {
		var aa, p2dm, a1 big.Int
		p2dm.Sub(&dm, &pow2s).Abs(&p2dm)
		aa.Mul(d, &pow2s).Div(&aa, &p2dm)
		if a.Cmp(&aa) == 1 {
			a.Set(&aa)
		}
		a1.Add(a, big.NewInt(1))
		t := floor_sum_unsigned(&a1, &pow2s, m, big.NewInt(0))
		t2 := floor_sum_unsigned(&a1, d, big.NewInt(1), big.NewInt(0))
		t.Sub(&t, &t2).Abs(&t)
		a.Sub(a, &t)
	}
	return *a
}

func main() {
	r := bufio.NewReader(os.Stdin)
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()

	var q int
	fmt.Fscan(r, &q)

	for i := 0; i < q; i++ {
		var n, d, m big.Int
		var s uint
		fmt.Fscan(r, &n, &d, &m, &s)
		c := solve(&n, &d, &m, s)
		fmt.Fprintln(w, c.String())
	}
}
0