結果

問題 No.1358 [Zelkova 2nd Tune *] 語るなら枚数を...
ユーザー kakel-sankakel-san
提出日時 2024-08-07 23:03:23
言語 C#
(.NET 8.0.203)
結果
AC  
実行時間 802 ms / 2,000 ms
コード長 2,522 bytes
コンパイル時間 15,510 ms
コンパイル使用メモリ 165,332 KB
実行使用メモリ 187,332 KB
最終ジャッジ日時 2024-08-07 23:03:46
合計ジャッジ時間 12,025 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 56 ms
30,848 KB
testcase_01 AC 52 ms
30,572 KB
testcase_02 AC 51 ms
30,700 KB
testcase_03 AC 53 ms
30,336 KB
testcase_04 AC 54 ms
30,336 KB
testcase_05 AC 51 ms
30,848 KB
testcase_06 AC 62 ms
30,976 KB
testcase_07 AC 61 ms
31,084 KB
testcase_08 AC 61 ms
30,976 KB
testcase_09 AC 59 ms
30,976 KB
testcase_10 AC 61 ms
31,104 KB
testcase_11 AC 724 ms
31,084 KB
testcase_12 AC 634 ms
31,104 KB
testcase_13 AC 802 ms
30,976 KB
testcase_14 AC 581 ms
31,104 KB
testcase_15 AC 658 ms
31,100 KB
testcase_16 AC 642 ms
187,332 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
  復元対象のプロジェクトを決定しています...
  /home/judge/data/code/main.csproj を復元しました (92 ms)。
MSBuild のバージョン 17.9.6+a4ecab324 (.NET)
  main -> /home/judge/data/code/bin/Release/net8.0/main.dll
  main -> /home/judge/data/code/bin/Release/net8.0/publish/

ソースコード

diff #

using System;
using static System.Console;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static int NN => int.Parse(ReadLine());
    static long[] NList => ReadLine().Split().Select(long.Parse).ToArray();
    public static void Main()
    {
        Solve();
    }
    static void Solve()
    {
        var t = NN;
        var ans = new long[t];
        for (var u = 0; u < t; ++u)
        {
            var c = NList;
            ans[u] = Count(c[0], c[1], c[2], c[3]);
        }
        WriteLine(string.Join("\n", ans));
    }
    static long Count(long n, long k, long h, long y)
    {
        if (h >= n && h >= k) return Count2(n, k, h, y);
        if (n >= k && n >= h) return Count2(k, h, n, y);
        return Count2(h, n, k, y);
    }
    static long Count2(long n, long k, long h, long y)
    {
        var ans = 0L;
        var mod = 1_000_000_007;
        var g = XGcd(n, k);
        var da = k / g.g;
        var db = n / g.g;
        for (var c = 0L; c * h <= y; ++c)
        {
            var p = y - c * h;
            if (p % g.g == 0)
            {
                var a = g.x * (p / g.g);
                var b = g.y * (p / g.g);
                if (a < 0)
                {
                    var d = (-a + da - 1) / da * da;
                    a += d;
                    b -= d / da * db;
                }
                else if (b < 0)
                {
                    var d = (-b + db - 1) / db * db;
                    a -= d / db * da;
                    b += d;
                }
                if (a >= 0 && b >= 0)
                {
                    ans = (ans + a / da + b / db + 1) % mod;
                }
            }
        }
        return ans;
    }
    static long GCD(long a, long b)
    {
        if (a < b) return GCD(b, a);
        if (a % b == 0) return b;
        return GCD(b, a % b);
    }
    // 拡張ユークリッド互除法 ax + by = gcd(a, b) を満たす x, y を求める
    public static (long g, long x, long y) XGcd(long a, long b)
    {
        long x0 = 1, y0 = 0, x1 = 0, y1 = 1;
        while (b != 0)
        {
            var q = a / b;
            var prevA = a;
            a = b;
            b = prevA % b;
            var prevX0 = x0;
            var prevY0 = y0;
            x0 = x1;
            x1 = prevX0 - q * x1;
            y0 = y1;
            y1 = prevY0 - q * y1;
        }
        return (a, x0, y0);
    }
}
0