結果
問題 | No.1371 交換門松列・松 |
ユーザー | 👑 hos.lyric |
提出日時 | 2021-01-29 22:27:25 |
言語 | D (dmd 2.106.1) |
結果 |
AC
|
実行時間 | 502 ms / 4,000 ms |
コード長 | 5,426 bytes |
コンパイル時間 | 1,159 ms |
コンパイル使用メモリ | 132,460 KB |
実行使用メモリ | 24,260 KB |
最終ジャッジ日時 | 2024-06-22 10:48:24 |
合計ジャッジ時間 | 9,440 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 1 ms
6,944 KB |
testcase_02 | AC | 1 ms
6,948 KB |
testcase_03 | AC | 1 ms
6,940 KB |
testcase_04 | AC | 1 ms
6,940 KB |
testcase_05 | AC | 1 ms
6,944 KB |
testcase_06 | AC | 1 ms
6,940 KB |
testcase_07 | AC | 1 ms
6,940 KB |
testcase_08 | AC | 1 ms
6,940 KB |
testcase_09 | AC | 1 ms
6,944 KB |
testcase_10 | AC | 1 ms
6,940 KB |
testcase_11 | AC | 1 ms
6,940 KB |
testcase_12 | AC | 1 ms
6,940 KB |
testcase_13 | AC | 1 ms
6,944 KB |
testcase_14 | AC | 1 ms
6,940 KB |
testcase_15 | AC | 1 ms
6,944 KB |
testcase_16 | AC | 1 ms
6,940 KB |
testcase_17 | AC | 1 ms
6,944 KB |
testcase_18 | AC | 462 ms
24,156 KB |
testcase_19 | AC | 467 ms
24,056 KB |
testcase_20 | AC | 374 ms
24,156 KB |
testcase_21 | AC | 363 ms
24,116 KB |
testcase_22 | AC | 364 ms
24,012 KB |
testcase_23 | AC | 488 ms
24,032 KB |
testcase_24 | AC | 500 ms
24,068 KB |
testcase_25 | AC | 500 ms
24,064 KB |
testcase_26 | AC | 489 ms
24,260 KB |
testcase_27 | AC | 502 ms
24,056 KB |
testcase_28 | AC | 496 ms
24,032 KB |
testcase_29 | AC | 489 ms
24,196 KB |
testcase_30 | AC | 498 ms
24,024 KB |
testcase_31 | AC | 499 ms
24,032 KB |
ソースコード
import std.conv, std.functional, std.range, std.stdio, std.string; import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons; import core.bitop; class EOFException : Throwable { this() { super("EOF"); } } string[] tokens; string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; } int readInt() { return readToken.to!int; } long readLong() { return readToken.to!long; } real readReal() { return readToken.to!real; } bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } } bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } } int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; } int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); } int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); } void bAdd(T)(T[] bit, int pos, T val) in { assert(0 <= pos && pos < bit.length, "bAdd: 0 <= pos < |bit| must hold"); } do { for (int x = pos; x < bit.length; x |= x + 1) { bit[x] += val; } } // sum of [0, pos) T bSum(T)(T[] bit, int pos) in { assert(0 <= pos && pos <= bit.length, "bSum: 0 <= pos <= |bit| must hold"); } do { T ret = 0; for (int x = pos - 1; x >= 0; x = (x & (x + 1)) - 1) { ret += bit[x]; } return ret; } bool isKadomatsu(int a, int b, int c) { return (((a > b && b < c) || (a < b && b > c)) && a != c); } bool isWeakKadomatsu(int a, int b, int c) { return ((a > b && b < c) || (a < b && b > c)); } void main() { try { for (; ; ) { const N = readInt(); auto A = new int[N]; foreach (i; 0 .. N) { A[i] = readInt() - 1; } if (A[0] > A[1]) { foreach (i; 0 .. N) { A[i] = N - 1 - A[i]; } } bool check(int i, int j) { const ai = A[i], aj = A[j]; bool ret = true; A[i] = aj; foreach (k; i - 2 .. i + 1) if (0 <= k && k + 3 <= N) ret = ret && isWeakKadomatsu(A[k], A[k + 1], A[k + 2]); A[i] = ai; A[j] = ai; foreach (k; j - 2 .. j + 1) if (0 <= k && k + 3 <= N) ret = ret && isWeakKadomatsu(A[k], A[k + 1], A[k + 2]); A[j] = aj; return ret; } long ans; foreach (s; 0 .. 2) foreach (t; 0 .. 2) { alias Entry = Tuple!(int, "x", int, "y", int, "type"); Entry[] es; for (int i = s; i < N; i += 2) { const y = A[i]; int x; if (s == 0) { x = N; if (i - 1 >= 0) chmin(x, A[i - 1]); if (i + 1 < N) chmin(x, A[i + 1]); assert(x > y); } else { x = -1; if (i - 1 >= 0) chmax(x, A[i - 1]); if (i + 1 < N) chmax(x, A[i + 1]); assert(x < y); } es ~= Entry(x, y, 0); } for (int i = t; i < N; i += 2) { const x = A[i]; int y; if (t == 0) { y = N; if (i - 1 >= 0) chmin(y, A[i - 1]); if (i + 1 < N) chmin(y, A[i + 1]); assert(y > x); } else { y = -1; if (i - 1 >= 0) chmax(y, A[i - 1]); if (i + 1 < N) chmax(y, A[i + 1]); assert(y < x); } es ~= Entry(x, y, 1); } debug { writeln("es = ", es); } if (s == 0) { foreach (ref e; es) { e.x *= -1; } } es.sort!((e, f) => ((e.x != f.x) ? (e.x < f.x) : (e.type > f.type))); debug { writeln("es = ", es); } auto bit = new long[N]; long num; foreach (ref e; es) { if (e.type == 0) { bit.bAdd(e.y, 1); } else { if (t == 0) { num += bit.bSum(e.y); } else { num += bit.bSum(N) - bit.bSum(e.y + 1); } } } ans += num; debug { long brt; foreach (i; 0 .. N) foreach (j; 0 .. N) { if (i % 2 == s && j % 2 == t) { if (check(i, j)) { ++brt; } } } writeln("brt = ", brt); writeln("num = ", num); assert(brt == num); } } foreach (i; 0 .. N) { foreach (j; i - 4 .. i + 4 + 1) { if (0 <= j && j < N) { if (check(i, j)) { --ans; } } } } ans /= 2; debug { writeln("ans = ", ans); } foreach (i; 0 .. N) { foreach (j; i + 1 .. i + 4 + 1) { if (0 <= j && j < N) { swap(A[i], A[j]); bool ok = true; foreach (k; min(i, j) - 2 .. max(i, j) + 1) { if (0 <= k && k + 3 <= N) { ok = ok && isKadomatsu(A[k], A[k + 1], A[k + 2]); } } swap(A[i], A[j]); if (ok) { ++ans; } } } } writeln(ans); } } catch (EOFException e) { } }