結果

問題 No.363 門松サイクル
ユーザー 紙ぺーぱー紙ぺーぱー
提出日時 2016-05-31 16:27:43
言語 C#(csc)
(csc 3.9.0)
結果
AC  
実行時間 530 ms / 4,000 ms
コード長 11,186 bytes
コンパイル時間 1,175 ms
コンパイル使用メモリ 114,816 KB
実行使用メモリ 45,944 KB
最終ジャッジ日時 2024-04-16 21:14:45
合計ジャッジ時間 9,740 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 27 ms
18,304 KB
testcase_01 AC 28 ms
18,304 KB
testcase_02 AC 31 ms
18,432 KB
testcase_03 AC 30 ms
18,432 KB
testcase_04 AC 30 ms
18,432 KB
testcase_05 AC 30 ms
18,432 KB
testcase_06 AC 31 ms
18,432 KB
testcase_07 AC 30 ms
18,560 KB
testcase_08 AC 30 ms
18,560 KB
testcase_09 AC 185 ms
31,360 KB
testcase_10 AC 189 ms
31,860 KB
testcase_11 AC 400 ms
44,276 KB
testcase_12 AC 479 ms
42,232 KB
testcase_13 AC 415 ms
42,348 KB
testcase_14 AC 320 ms
40,696 KB
testcase_15 AC 340 ms
43,252 KB
testcase_16 AC 260 ms
35,576 KB
testcase_17 AC 530 ms
44,792 KB
testcase_18 AC 488 ms
44,280 KB
testcase_19 AC 329 ms
45,944 KB
testcase_20 AC 460 ms
44,528 KB
testcase_21 AC 511 ms
44,920 KB
testcase_22 AC 451 ms
43,624 KB
testcase_23 AC 428 ms
39,928 KB
testcase_24 AC 27 ms
18,304 KB
testcase_25 AC 28 ms
18,304 KB
testcase_26 AC 242 ms
44,784 KB
testcase_27 AC 245 ms
44,784 KB
testcase_28 AC 400 ms
44,528 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc)
Copyright (C) Microsoft Corporation. All rights reserved.

ソースコード

diff #

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using Debug = System.Diagnostics.Debug;
using StringBuilder = System.Text.StringBuilder;
using System.Numerics;
using Point = System.Numerics.Complex;
using Number = System.Numerics.BigInteger;
namespace Program
{
    public class Solver
    {
        public void Solve()
        {
            var n = sc.Integer();
            var a = sc.Integer(n);
            var T = new Tree(n, a);
            for (int i = 0; i < n - 1; i++)
            {
                var f = sc.Integer() - 1;
                var t = sc.Integer() - 1;
                T.AddEdge(f, t);
            }

            T.Build(0);
            var q = sc.Integer();
            for (int i = 0; i < q; i++)
            {
                var f = sc.Integer() - 1;
                var t = sc.Integer() - 1;
                var lca = T.GetLCA(f, t);
                var k = T.depth[f] + T.depth[t] - 2 * T.depth[lca] + 1;
                if (k < 3)
                {
                    IO.Printer.Out.WriteLine("NO");
                    continue;
                }
                var A = T.Query(lca, f);
                var B = T.Query(lca, t);
                var ans = true;
                ans &= A;
                ans &= B;

                var pf = T.par[f];
                var pt = T.par[t];
                if (f == lca)
                {
                    var ptlca = T.GetAncestorAt(t, T.depth[lca] + 1);
                    ans &= ok(a[f], a[t], a[pt]);
                    ans &= ok(a[t], a[lca], a[ptlca]);
                }
                else if (t == lca)
                {
                    var pflca = T.GetAncestorAt(f, T.depth[lca] + 1);
                    ans &= ok(a[pf], a[f], a[t]);
                    ans &= ok(a[f], a[lca], a[pflca]);
                }
                else
                {
                    var ptlca = T.GetAncestorAt(t, T.depth[lca] + 1);
                    var pflca = T.GetAncestorAt(f, T.depth[lca] + 1);
                    ans &= ok(a[pf], a[f], a[t]);
                    ans &= ok(a[f], a[t], a[pt]);
                    ans &= ok(a[pflca], a[lca], a[ptlca]);
                }
                if (ans)
                    IO.Printer.Out.WriteLine("YES");
                else IO.Printer.Out.WriteLine("NO");
            }
        }
        public bool ok(int a, int b, int c)
        {
            if (a == b || b == c || a == c) return false;
            if (a < b && b > c) return true;
            if (a > b && b < c) return true;
            return false;
        }
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());
        static T[] Enumerate<T>(int n, Func<int, T> f) { var a = new T[n]; for (int i = 0; i < n; ++i) a[i] = f(i); return a; }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}
#region main
static class Ex
{
    static public string AsString(this IEnumerable<char> ie) { return new string(System.Linq.Enumerable.ToArray(ie)); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") { return string.Join(st, ie); }
    static public void Main()
    {
        var solver = new Program.Solver();
        solver.Solve();
        Program.IO.Printer.Out.Flush();
    }
}
#endregion
#region Ex
namespace Program.IO
{
    using System.IO;
    using System.Text;
    using System.Globalization;
    public class Printer : StreamWriter
    {
        static Printer() { Out = new Printer(Console.OpenStandardOutput()) { AutoFlush = false }; }
        public static Printer Out { get; set; }
        public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
        public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
        public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
        public void Write<T>(string format, T[] source) { base.Write(format, source.OfType<object>().ToArray()); }
        public void WriteLine<T>(string format, T[] source) { base.WriteLine(format, source.OfType<object>().ToArray()); }
    }
    public class StreamScanner
    {
        public StreamScanner(Stream stream) { str = stream; }
        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream { get { return isEof; } }
        private byte read()
        {
            if (isEof) return 0;
            if (ptr >= len) { ptr = 0; if ((len = str.Read(buf, 0, 1024)) <= 0) { isEof = true; return 0; } }
            return buf[ptr++];
        }
        public char Char() { byte b = 0; do b = read(); while ((b < 33 || 126 < b) && !isEof); return (char)b; }

        public string Scan()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
                sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n'; b = (char)read())
                if (b == 0) break;
                else if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long()
        {
            if (isEof) return long.MinValue;
            long ret = 0; byte b = 0; var ng = false;
            do b = read();
            while (b != 0 && b != '-' && (b < '0' || '9' < b));
            if (b == 0) return long.MinValue;
            if (b == '-') { ng = true; b = read(); }
            for (; true; b = read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }
        public int Integer() { return (isEof) ? int.MinValue : (int)Long(); }
        public double Double() { var s = Scan(); return s != "" ? double.Parse(s, CultureInfo.InvariantCulture) : double.NaN; }
        private T[] enumerate<T>(int n, Func<T> f)
        {
            var a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = f();
            return a;
        }

        public char[] Char(int n) { return enumerate(n, Char); }
        public string[] Scan(int n) { return enumerate(n, Scan); }
        public double[] Double(int n) { return enumerate(n, Double); }
        public int[] Integer(int n) { return enumerate(n, Integer); }
        public long[] Long(int n) { return enumerate(n, Long); }
    }
}
#endregion
#region Tree

public class Tree
{
    public bool ok(int a, int b, int c)
    {
        if (a == b || b == c || a == c) return false;
        if (a < b && b > c) return true;
        if (a > b && b < c) return true;
        return false;
    }
    public bool Query(int from, int to)
    {
        switch (depth[to] - depth[from])
        {
            case 0: return true;
            case 1: return val[from] != val[to];
            case 2: return ok(val[from], val[par[to]], val[to]);
            default:
                var ans = true;
                var d = depth[from] + 2;
                for (int i = 0; i < 20; i++)
                    if ((((depth[to] - d) >> i) & 1) == 1)
                    {
                        ans &= OK[i, to];
                        to = parent[i, to];
                    }
                return ans & Query(from, to);

        }
    }
    List<Edge>[] G;
    public int[] par;
    int[] pos;
    int[,] parent;
    public int[] depth;
    int[] val;
    bool[,] OK;
    public Tree(int n, int[] a)
    {
        G = Enumerate(n, x => new List<Edge>());
        pos = new int[n];
        depth = new int[n];
        par = new int[n];
        parent = new int[20, n];
        OK = new bool[20, n];
        val = a;
    }
    public void AddEdge(int f, int t)
    {
        G[f].Add(new Edge(f, t));
        G[t].Add(new Edge(t, f));
    }
    #region impl
    public void Build(int root)
    {
        Walk(root);
        BuildLCA();

    }
    public void Walk(int root)
    {
        par[root] = -1;
        var q = new Queue<int>();
        q.Enqueue(0);
        while (q.Any())
        {
            var cur = q.Dequeue();
            var pre = par[cur];
            Debug.WriteLine("{0} {1}", pre, cur);
            if (pre == -1)
                OK[0, cur] = true;
            else if (par[pre] == -1)
                OK[0, cur] = val[cur] == val[pre];
            else
                OK[0, cur] = ok(val[cur], val[pre], val[par[pre]]);
            foreach (var e in G[cur])
            {
                if (e.to == pre) continue;
                if (e.from == pre) continue;
                depth[e.to] = depth[cur] + 1;
                par[e.to] = cur;
                q.Enqueue(e.to);
            }
        }
    }

    void BuildLCA()
    {
        for (int k = 0; k < 19; k++)
            for (int v = 0; v < G.Length; v++)
                parent[k, v] = -1;
        for (int i = 0; i < G.Length; i++)
            parent[0, i] = par[i];
        for (int k = 0; k < 19; k++)
        {
            for (int v = 0; v < G.Length; v++)
                if (parent[k, v] < 0) parent[k + 1, v] = -1;
                else
                {
                    parent[k + 1, v] = parent[k, parent[k, v]];
                    OK[k + 1, v] = OK[k, v] & OK[k, parent[k, v]];
                }
        }

    }


    public int To(Edge t) { return t.to; }
    public int GetLCA(int u, int v)
    {
        if (depth[u] > depth[v]) { var tmp = u; u = v; v = tmp; }
        for (int k = 0; k < 20; k++)
            if ((((depth[v] - depth[u]) >> k) & 1) == 1)
                v = parent[k, v];
        if (u == v)
            return u;
        for (int i = 19; i >= 0; i--)
            if (parent[i, u] != parent[i, v])
            {
                u = parent[i, u];
                v = parent[i, v];
            }
        return parent[0, u];
    }
    public int GetAncestor(int v, int k)
    {
        var to = depth[v] - k;
        for (int i = 0; i < 20; i++)
            if ((((depth[v] - to) >> i) & 1) == 1)
                v = parent[i, v];
        return v;
    }
    public int GetAncestorAt(int v, int d)
    {
        if (depth[v] < d)
            throw new Exception();
        for (int i = 0; i < 20; i++)
            if ((((depth[v] - d) >> i) & 1) == 1)
                v = parent[i, v];
        return v;
    }
    static T[] Enumerate<T>(int n, Func<int, T> f) { var a = new T[n]; for (int i = 0; i < n; ++i) a[i] = f(i); return a; }
    #endregion
}
#endregion
#region TreeEdge
public struct Edge
{
    public int from, to;
    public Edge(int f, int t)
    {
        from = f; to = t;
    }
    public override string ToString()
    {
        return string.Format("{0}->{1}", from, to);
    }
}
#endregion
#region Triplet<T>

public struct Triplet<T>
{
    public T I, J, K;
    public Triplet(T i, T j, T k) : this() { I = i; J = j; K = k; }
    public Triplet(params T[] arg) : this(arg[0], arg[1], arg[2]) { }
    public override string ToString() { return string.Format("{0} {1} {2}", I, J, K); }
}
#endregion
0