結果
問題 |
No.2716 Falcon Method
|
ユーザー |
|
提出日時 | 2025-07-31 02:39:45 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 201 ms / 2,000 ms |
コード長 | 4,453 bytes |
コンパイル時間 | 3,278 ms |
コンパイル使用メモリ | 203,116 KB |
実行使用メモリ | 19,340 KB |
最終ジャッジ日時 | 2025-07-31 02:39:53 |
合計ジャッジ時間 | 7,203 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 28 |
ソースコード
import std; void main () { int N, Q; readln.read(N, Q); string S = readln.chomp; auto H = new int[](Q); auto W = new int[](Q); auto P = new int[](Q); foreach (i; 0 .. Q) { readln.read(H[i], W[i], P[i]); } auto accD = new int[](2 * N + 1); auto accR = new int[](2 * N + 1); foreach (i; 0 .. 2 * N) { int u = S[i % N] == 'D' ? 1 : 0; int v = S[i % N] == 'R' ? 1 : 0; accD[i + 1] = accD[i] + u; accR[i + 1] = accR[i] + v; } // stからはじまってup個の1を含む最小項数を累積和accから計算 long f (int[] acc, int st, int up) { long ret = 0; int all = acc[N]; if (all == 0) { return long.max; } if (up % all == 0) { ret += 1L * (up / all - 1) * N; up = all; } else { ret += 1L * up / all * N; up %= all; } auto br = bsearch!((int id) => up <= acc[st + id] - acc[st])(2 * N - st, 0); return ret + br.value; } // g(acc, up) := stからはじまって先頭up項の総和を累積和accから計算 long g (int[] acc, int st, long up) { long ret = up / N * acc[N]; up %= N; return ret + acc[st + up] - acc[st]; } auto ans = new long[](Q); foreach (i; 0 .. Q) { long Y = f(accD, P[i], H[i]); long X = f(accR, P[i], W[i]); long Z = min(X, Y); ans[i] = Z + P[i]; ans[i] %= N; } writefln("%(%s\n%)", ans); } void read (T...) (string S, ref T args) { import std.conv : to; import std.array : split; auto buf = S.split; foreach (i, ref arg; args) { arg = buf[i].to!(typeof(arg)); } } import std.traits : isIntegral; import std.int128 : Int128; class NoTrueRangeException: Exception { import std.exception: basicExceptionCtors; mixin basicExceptionCtors; } class BsearchException: Exception { import std.exception: basicExceptionCtors; mixin basicExceptionCtors; } struct BsearchResult (T) { import std.format: format; private bool has_value = true; private T l, r; private T _value; this (T _l, T _r) { this.l = _l; this.r = _r; this.has_value = false; } this (T _l, T _r, T _value) { this.l = _l; this.r = _r; this._value = _value; } bool empty () { return !this.has_value; } T value () { if (this.empty()) { throw new NoTrueRangeException( format("No true condition found in the range [%s, %s].", l, r)); } return _value; }; } BsearchResult!T bsearch (alias func, T) (T l, T r) if ((isIntegral!(T) || is(T == Int128)) && !is(T == byte) && !is(T == ubyte) && !is(T == short) && !is(T == ushort)) { import std.traits : isCallable, ReturnType, Parameters; import std.meta : AliasSeq; static assert(isCallable!(func)); static assert(is(ReturnType!(func) == bool)); static assert(is(Parameters!(func) == AliasSeq!(T))); import std.algorithm.comparison : min, max; T L = l, R = r; if (l == r) { if (func(l)) return BsearchResult!(T)(L, R, l); return BsearchResult!(T)(L, R); } while (min(l, r) + 1 < max(l, r)) { T m = midpoint(l, r); if (func(m)) { l = m; } else { r = m; } } bool lb = func(l); if (!lb) return BsearchResult!(T)(L, R); bool rb = func(r); if (rb) return BsearchResult!(T)(L, R, r); if (!rb) return BsearchResult!(T)(L, R, l); throw new BsearchException(format("This code path should never be reached. l: %s, r: %s.", L, R)); } T midpoint (T) (T a, T b) if (isIntegral!(T) || is(T == Int128)) { static if (is(T == short) || is(T == ushort) || is(T == byte) || is(T == ubyte)) { import std.conv : to; int x = a, y = b; return midpoint(x, y).to!(T); } else { import std.math.algebraic : abs; import std.algorithm.comparison : min, max; int as = (0 <= a) ? 1 : -1, bs = (0 <= b) ? 1 : -1; if (as == bs) { if (as == 1) { return min(a, b) + (max(a, b) - min(a, b)) / 2; } return max(a, b) + (min(a, b) - max(a, b)) / 2; } return (a + b) / 2; } }