結果
問題 | No.363 門松サイクル |
ユーザー | FF256grhy |
提出日時 | 2016-04-19 15:24:25 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 171 ms / 4,000 ms |
コード長 | 3,074 bytes |
コンパイル時間 | 188 ms |
コンパイル使用メモリ | 26,344 KB |
実行使用メモリ | 20,280 KB |
最終ジャッジ日時 | 2024-10-04 14:06:45 |
合計ジャッジ時間 | 3,943 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
7,540 KB |
testcase_01 | AC | 2 ms
7,800 KB |
testcase_02 | AC | 2 ms
7,680 KB |
testcase_03 | AC | 3 ms
7,680 KB |
testcase_04 | AC | 3 ms
9,648 KB |
testcase_05 | AC | 3 ms
7,544 KB |
testcase_06 | AC | 2 ms
7,672 KB |
testcase_07 | AC | 3 ms
7,556 KB |
testcase_08 | AC | 3 ms
7,728 KB |
testcase_09 | AC | 54 ms
14,840 KB |
testcase_10 | AC | 48 ms
13,632 KB |
testcase_11 | AC | 125 ms
20,076 KB |
testcase_12 | AC | 129 ms
19,328 KB |
testcase_13 | AC | 106 ms
19,324 KB |
testcase_14 | AC | 84 ms
19,628 KB |
testcase_15 | AC | 117 ms
19,716 KB |
testcase_16 | AC | 92 ms
17,416 KB |
testcase_17 | AC | 171 ms
20,176 KB |
testcase_18 | AC | 112 ms
20,120 KB |
testcase_19 | AC | 83 ms
20,204 KB |
testcase_20 | AC | 109 ms
20,280 KB |
testcase_21 | AC | 159 ms
20,052 KB |
testcase_22 | AC | 112 ms
19,808 KB |
testcase_23 | AC | 127 ms
20,056 KB |
testcase_24 | AC | 0 ms
7,668 KB |
testcase_25 | AC | 2 ms
7,540 KB |
testcase_26 | AC | 154 ms
20,084 KB |
testcase_27 | AC | 155 ms
20,008 KB |
testcase_28 | AC | 142 ms
20,244 KB |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:63:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 63 | scanf("%d", &n); | ~~~~~^~~~~~~~~~ main.cpp:64:39: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 64 | for(i = 0; i < n; i++) { scanf("%d", &a[i]); } | ~~~~~^~~~~~~~~~~~~ main.cpp:65:43: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 65 | for(i = 0; i < n - 1; i++) { scanf("%d%d", &x[i], &y[i]); x[i]--; y[i]--; } | ~~~~~^~~~~~~~~~~~~~~~~~~~~~ main.cpp:66:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 66 | scanf("%d", &q); | ~~~~~^~~~~~~~~~ main.cpp:67:43: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 67 | for(i = 0; i < q ; i++) { scanf("%d%d", &u[i], &v[i]); u[i]--; v[i]--; } | ~~~~~^~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <stdio.h> int isK(int a, int b, int c) { return ( (a < b && b > c && a != c) || (a > b && b < c && a != c) ); } #define MAX 100000 #define NIL 0 #define ROOT 0 int n, a[MAX], x[MAX], y[MAX], q, u[MAX], v[MAX]; int first[MAX], last[MAX], list_val[MAX * 2 + 1], list_next[MAX * 2 + 1], ptr = 1; int queue_val[MAX], get, set; int height[MAX], ancestor[MAX][17], is_kado[MAX][17], flag[MAX]; // ancestor は 2^n 上のノード, is_kado は 2^n + 1 までが門松列かどうか void add(int xx, int yy) { if(first[xx] == NIL) { first[xx] = ptr; } else { list_next[ last[xx] ] = ptr; } last[xx] = ptr; list_val[ptr] = yy; list_next[ptr] = NIL; ptr++; } int up(int s, int n) { int i = 0; while(n) { if(n % 2) { s = ancestor[s][i]; } n /= 2; i++; } return s; } int len(int n) { int i = 0; while(n) { n /= 2; i++; } return i; } int is_kado_func(int s, int t) { // s から tの次 まで int n = height[s] - height[t]; int i, ans = 1; for(i = 0; i < len(n); i++) { if(n & (1 << i)) { ans &= is_kado[s][i]; s = ancestor[s][i]; } } return ans; } int main() { int i, j; scanf("%d", &n); for(i = 0; i < n; i++) { scanf("%d", &a[i]); } for(i = 0; i < n - 1; i++) { scanf("%d%d", &x[i], &y[i]); x[i]--; y[i]--; } scanf("%d", &q); for(i = 0; i < q ; i++) { scanf("%d%d", &u[i], &v[i]); u[i]--; v[i]--; } for(i = 0; i < n - 1; i++) { add(x[i], y[i]); add(y[i], x[i]); } queue_val[set] = ROOT; set++; flag[ROOT] = 1; height[ROOT] = 0; while(get != set) { int qv = queue_val[get]; int p = first[qv]; while(p != NIL) { int lv = list_val[p]; if(! flag[lv]) { flag[lv] = 1; queue_val[set] = lv; set++; height[lv] = height[qv] + 1; ancestor[lv][0] = qv; for(i = 0; i < len(height[lv]) - 1; i++) { ancestor[lv][i + 1] = ancestor[ ancestor[lv][i] ][i]; } if(height[lv] >= 2) { is_kado[lv][0] = isK( a[lv], a[ ancestor[lv][0] ], a[ ancestor[lv][1] ] ); for(i = 0; i < len(height[lv] - 1) - 1; i++) { is_kado[lv][i + 1] = is_kado[lv][i] && is_kado[ ancestor[lv][i] ][i]; } } } p = list_next[p]; } get++; } for(i = 0; i < q; i++) { if(height[ u[i] ] < height[ v[i] ]) { int temp = u[i]; u[i] = v[i]; v[i] = temp; } int diff = height[ u[i] ] - height[ v[i] ]; int s = up(u[i], diff); int t = v[i]; int ans; if(s != t) { for(j = len(height[s]) - 1; 0 <= j; j--) { if(ancestor[s][j] != ancestor[t][j]) { s = ancestor[s][j]; t = ancestor[t][j]; } } int c = ancestor[s][0]; int uu = ancestor[ u[i] ][0]; int vv = ancestor[ v[i] ][0]; ans = ( isK(a[s], a[c], a[t]) && isK(a[uu], a[u[i]], a[v[i]]) && isK(a[vv], a[v[i]], a[u[i]]) && is_kado_func(u[i], s) && is_kado_func(v[i], t) ); } else { int uu = ancestor[ u[i] ][0]; int vv = up(u[i], diff - 1); ans = ( isK(a[uu], a[u[i]], a[v[i]]) && isK(a[vv], a[v[i]], a[u[i]]) && is_kado_func(u[i], vv) ); } printf("%s\n", ans ? "YES" : "NO"); } return 0; }