結果

問題 No.2220 Range Insert & Point Mex
ユーザー 👑 kakel-sankakel-san
提出日時 2023-09-03 22:11:12
言語 C#(csc)
(csc 3.9.0)
結果
AC  
実行時間 998 ms / 2,000 ms
コード長 9,040 bytes
コンパイル時間 1,473 ms
コンパイル使用メモリ 70,736 KB
実行使用メモリ 78,192 KB
最終ジャッジ日時 2023-09-03 22:11:36
合計ジャッジ時間 22,668 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 76 ms
23,016 KB
testcase_01 AC 73 ms
23,004 KB
testcase_02 AC 76 ms
22,972 KB
testcase_03 AC 77 ms
23,116 KB
testcase_04 AC 76 ms
23,116 KB
testcase_05 AC 79 ms
23,116 KB
testcase_06 AC 80 ms
23,024 KB
testcase_07 AC 77 ms
23,032 KB
testcase_08 AC 77 ms
23,040 KB
testcase_09 AC 78 ms
25,144 KB
testcase_10 AC 79 ms
25,068 KB
testcase_11 AC 77 ms
25,100 KB
testcase_12 AC 76 ms
23,048 KB
testcase_13 AC 840 ms
76,052 KB
testcase_14 AC 838 ms
76,040 KB
testcase_15 AC 818 ms
74,116 KB
testcase_16 AC 847 ms
76,088 KB
testcase_17 AC 839 ms
76,080 KB
testcase_18 AC 812 ms
76,160 KB
testcase_19 AC 839 ms
78,192 KB
testcase_20 AC 859 ms
74,656 KB
testcase_21 AC 787 ms
72,664 KB
testcase_22 AC 861 ms
76,492 KB
testcase_23 AC 691 ms
69,628 KB
testcase_24 AC 588 ms
64,476 KB
testcase_25 AC 643 ms
58,676 KB
testcase_26 AC 479 ms
63,528 KB
testcase_27 AC 264 ms
47,544 KB
testcase_28 AC 309 ms
48,300 KB
testcase_29 AC 291 ms
47,132 KB
testcase_30 AC 290 ms
45,108 KB
testcase_31 AC 648 ms
65,360 KB
testcase_32 AC 483 ms
54,916 KB
testcase_33 AC 695 ms
60,692 KB
testcase_34 AC 724 ms
72,528 KB
testcase_35 AC 965 ms
70,308 KB
testcase_36 AC 644 ms
62,828 KB
testcase_37 AC 807 ms
64,300 KB
testcase_38 AC 998 ms
73,944 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

using System;
using static System.Console;
using System.Linq;
using System.Collections.Generic;
class Program
{
    static int NN => int.Parse(ReadLine());
    static int[] NList => ReadLine().Split().Select(int.Parse).ToArray();
    static int[][] NArr(long n) => Enumerable.Repeat(0, (int)n).Select(_ => NList).ToArray();
    public static void Main()
    {
        Solve();
    }
    static void Solve()
    {
        var n = NN;
        var map = NArr(n);
        var q = NN;
        var a = NList;
        WriteLine(Mex(n, map, q, a));
    }
    static string Mex(int n, int[][] map, int q, int[] a)
    {
        var set = new HashSet<int>();
        set.Add(1);
        set.Add(1_000_000_001);
        for (var i = 0; i < n; ++i)
        {
            set.Add(map[i][0]);
            set.Add(map[i][1] + 1);
        }
        foreach (var ai in a) set.Add(ai);
        var list = new List<int>(set);
        list.Sort();
        var dic = new Dictionary<int, int>();
        for (var i = 0; i < list.Count; ++i) dic[list[i]] = i;

        var rlist = new List<(int l, int r)>[n + 1];
        for (var i = 0; i < rlist.Length; ++i) rlist[i] = new List<(int l, int r)>();
        for (var i = 0; i < n; ++i) if (map[i][2] < rlist.Length)
        {
            rlist[map[i][2]].Add((map[i][0], map[i][1] + 1));
        }
        for (var i = 0; i < rlist.Length; ++i)
        {
            if (rlist[i].Count == 0)
            {
                rlist[i] = new List<(int l, int r)>{ (1, 1_000_000_001) };
                continue;
            }
            rlist[i].Sort((l, r) =>
            {
                var d = l.l.CompareTo(r.l);
                if (d != 0) return d;
                return l.r.CompareTo(r.r);
            });
            // WriteLine($"rlist[{i}]: {string.Join(" ", rlist[i])}");
            var nlist = new List<(int l, int r)>();
            nlist.Add(rlist[i][0]);
            for (var j = 1; j < rlist[i].Count; ++j)
            {
                var prev = nlist[nlist.Count - 1];
                if (prev.r >= rlist[i][j].l)
                {
                    nlist[nlist.Count - 1] = (prev.l, Math.Max(prev.r, rlist[i][j].r));
                }
                else
                {
                    nlist.Add(rlist[i][j]);
                }
            }
            // WriteLine($"nlist[{i}]: {string.Join(" ", nlist)}");
            var exlist = new List<(int l, int r)>();
            if (1 < nlist[0].l) exlist.Add((1, nlist[0].l));
            for (var j = 1; j < nlist.Count; ++j) exlist.Add((nlist[j - 1].r, nlist[j].l));
            if (nlist[nlist.Count - 1].r < 1_000_000_001) exlist.Add((nlist[nlist.Count - 1].r, 1_000_000_001));
            rlist[i] = exlist;
        }
        var seg = new LazySegTree<int, int>(list.Count, new Op());
        for (var i = n; i >= 0; --i)
        {
            foreach (var ex in rlist[i])
            {
                seg.Apply(dic[ex.l], dic[ex.r], i);
                // WriteLine($"seg[{dic[ex.l]}..{dic[ex.r]}] = {i}");
                // for (var j = 0; j < list.Count; ++j) Write(seg.Get(j) + " ");
                // WriteLine();
            }
        }
        var ans = new int[q];
        for (var i = 0; i < q; ++i) ans[i] = seg.Get(dic[a[i]]);
        return (string.Join("\n", ans));
    }
    class Op : ILazySegTreeOperator<int, int>
    {
        public int Composition(int f, int g)
        {
            return f == Id() ? g : f;
        }
        public int E()
        {
            return int.MaxValue;
        }
        public int Id()
        {
            return int.MaxValue;
        }
        public int Mapping(int f, int x)
        {
            return f == Id() ? x : f;
        }
        int ILazySegTreeOperator<int, int>.Op(int a, int b)
        {
            return Math.Min(a, b);
        }
    }
    interface ILazySegTreeOperator<S, F>
    {
        /// <summary>集合S上の二項演算 S×S → S </summary>
        S Op(S a, S b);
        /// <summary>Sの単位元</summary>
        S E();
        /// <summary>写像f(x) ※更新、加算などの処理</summary>
        S Mapping(F f, S x);
        /// <summary>写像の合成 f ○ g ※後に行う操作がfとなる(</summary>
        F Composition(F f, F g);
        /// <summary>恒等写像 id</summary>
        F Id();
    }
    // モノイドの型 S
    // 写像の型 F
    // 以下の関数を格納する T
    //   ・: S × S → S を計算する関数 S op(S a, S b)
    //   e を返す関数 S e()
    //   f(x) を返す関数 S mapping(F f, S x)
    //   f○gを返す関数 F composition(F f, F g)
    //   idを返す関数 F id()
    // S,Fはreadonlyにしておくと速い
    // Tの関数オーバーフローに注意
    class LazySegTree<S, F>
    {
        int _n;
        int size;
        int log;
        List<S> d;
        List<F> lz;
        ILazySegTreeOperator<S, F> op;
        public LazySegTree(int n, ILazySegTreeOperator<S, F> op)
        {
            _n = n;
            var v = new S[n];
            for (var i = 0; i < v.Length; ++i) v[i] = op.E();
            Init(v, op);
        }
        public LazySegTree(S[] v, ILazySegTreeOperator<S, F> op)
        {
            _n = v.Length;
            Init(v, op);
        }
        private void Init(S[] v, ILazySegTreeOperator<S, F> op)
        {
            size = 1;
            log = 0;
            this.op = op;
            while (size < v.Length)
            {
                size <<= 1;
                ++log;
            }
            d = Enumerable.Repeat(op.E(), size * 2).ToList();
            lz = Enumerable.Repeat(op.Id(), size).ToList();
            for (var i = 0; i < v.Length; ++i) d[size + i] = v[i];
            for (var i = size - 1; i >= 1; --i) Update(i);
        }

        /// <summary>一点更新</summary>
        public void Set(int pos, S x)
        {
            pos += size;
            for (var i = log; i >= 1; --i) Push(pos >> i);
            d[pos] = x;
            for (var i = 1; i <= log; ++i) Update(pos >> i);
        }

        /// <summary>一点取得</summary>
        public S Get(int pos)
        {
            pos += size;
            for (var i = log; i >= 1; --i) Push(pos >> i);
            return d[pos];
        }

        /// <summary>区間取得 op(a[l..r-1])</summary>
        public S Prod(int l, int r)
        {
            if (l == r) return op.E();
            l += size;
            r += size;
            for (var i = log; i >= 1; --i)
            {
                if (((l >> i) << i) != l) Push(l >> i);
                if (((r >> i) << i) != r) Push(r >> i);
            }
            S sml = op.E();
            S smr = op.E();
            while (l < r)
            {
                if ((l & 1) != 0) sml = op.Op(sml, d[l++]);
                if ((r & 1) != 0) smr = op.Op(d[--r], smr);
                l >>= 1;
                r >>= 1;
            }

            return op.Op(sml, smr);
        }

        /// <summary>全体取得 op(a[0..n-1])</summary>
        public S AllProd() => d[1];

        /// <summary>なにこれ a[p] = op_st(a[p], x)</summary>
        public void Apply(int pos, F f)
        {
            pos += size;
            for (var i = log; i >= 1; --i) Push(pos >> i);
            d[pos] = op.Mapping(f, d[pos]);
            for (var i = 1; i <= log; ++i) Update(pos >> i);
        }

        /// <summary>区間更新 i = l..r-1 について a[i] = op_st(a[i], x)</summary>
        public void Apply(int l, int r, F f)
        {
            if (l == r) return;
            l += size;
            r += size;

            for (var i = log; i >= 1; --i)
            {
                if (((l >> i) << i) != l) Push(l >> i);
                if (((r >> i) << i) != r) Push((r - 1) >> i);
            }
            {
                var l2 = l;
                var r2 = r;
                while (l < r)
                {
                    if ((l & 1) != 0) AllApply(l++, f);
                    if ((r & 1) != 0) AllApply(--r, f);
                    l >>= 1;
                    r >>= 1;
                }
                l = l2;
                r = r2;
            }
            for (var i = 1; i <= log; ++i)
            {
                if (((l >> i) << i) != l) Update(l >> i);
                if (((r >> i) << i) != r) Update((r - 1) >> i);
            }
        }
        void Update(int k)
        {
            d[k] = op.Op(d[2 * k], d[2 * k + 1]);
        }
        void AllApply(int k, F f)
        {
            d[k] = op.Mapping(f, d[k]);
            if (k < size) lz[k] = op.Composition(f, lz[k]);
        }
        void Push(int k)
        {
            AllApply(2 * k, lz[k]);
            AllApply(2 * k + 1, lz[k]);
            lz[k] = op.Id();
        }
    }
}
0