結果

問題 No.1000 Point Add and Array Add
ユーザー mbanmban
提出日時 2020-03-12 12:31:51
言語 C#(csc)
(csc 3.9.0)
結果
AC  
実行時間 737 ms / 2,000 ms
コード長 5,679 bytes
コンパイル時間 3,431 ms
コンパイル使用メモリ 105,396 KB
実行使用メモリ 74,292 KB
最終ジャッジ日時 2023-08-11 03:57:14
合計ジャッジ時間 13,496 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 73 ms
48,196 KB
testcase_01 AC 73 ms
48,428 KB
testcase_02 AC 72 ms
48,172 KB
testcase_03 AC 71 ms
48,440 KB
testcase_04 AC 69 ms
48,328 KB
testcase_05 AC 70 ms
48,424 KB
testcase_06 AC 73 ms
48,212 KB
testcase_07 AC 76 ms
48,320 KB
testcase_08 AC 75 ms
48,212 KB
testcase_09 AC 76 ms
48,264 KB
testcase_10 AC 75 ms
48,316 KB
testcase_11 AC 75 ms
48,316 KB
testcase_12 AC 85 ms
48,904 KB
testcase_13 AC 77 ms
48,712 KB
testcase_14 AC 90 ms
49,176 KB
testcase_15 AC 81 ms
49,088 KB
testcase_16 AC 455 ms
66,452 KB
testcase_17 AC 409 ms
70,692 KB
testcase_18 AC 638 ms
69,680 KB
testcase_19 AC 627 ms
73,644 KB
testcase_20 AC 403 ms
70,288 KB
testcase_21 AC 736 ms
74,292 KB
testcase_22 AC 501 ms
73,512 KB
testcase_23 AC 737 ms
74,292 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 CompLib.Collections.Generic;
using CompLib.Util;

class Program
{
    private int N, Q;
    private long[] A;
    private long[] B;

    private char[] C;
    private int[] X, Y;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        Q = sc.NextInt();
        A = sc.LongArray();

        C = new char[Q];
        X = new int[Q];
        Y = new int[Q];
        for (int i = 0; i < Q; i++)
        {
            C[i] = sc.NextChar();
            X[i] = sc.NextInt();
            Y[i] = sc.NextInt();
        }

        // 元のaの値、Aに足される値それぞれの足される回数を求める

        var ruq = new RangeUpdateQuery<long>((a, b) => a + b, 0);
        B = new long[N];
        for (int i = Q - 1; i >= 0; i--)
        {
            if (C[i] == 'A')
            {
                B[X[i] - 1] += ruq[X[i] - 1] * Y[i];
            }
            else
            {
                ruq.Update(X[i] - 1, Y[i], 1);
            }
        }

        for (int i = 0; i < N; i++)
        {
            B[i] += ruq[i] * A[i];
        }

        Console.WriteLine(string.Join(" ", B));
    }

    public static void Main(string[] args) => new Program().Solve();
}

namespace CompLib.Collections.Generic
{
    using System;

    public class RangeUpdateQuery<T>
    {
        // 制約に合った2の冪
        private const int N = 1 << 21;
        private T[] _array;
        private readonly bool[] flag;

        private readonly T _identity;
        private readonly Func<T, T, T> _operation;

        /// <summary>
        /// 区間更新、点取得
        /// </summary>
        /// <param name="operation">更新用の演算</param>
        /// <param name="identity">(T, operation)の左単位元</param>
        public RangeUpdateQuery(Func<T, T, T> operation, T identity)
        {
            _identity = identity;
            _operation = operation;
            _array = new T[N * 2];
            for (int i = 1; i < N * 2; i++)
            {
                _array[i] = _identity;
            }

            flag = new bool[N * 2];
        }

        private void Eval(int k, int l, int r)
        {
            if (flag[k])
            {
                if (r - l > 1)
                {
                    _array[k * 2] = _operation(_array[k * 2], _array[k]);
                    flag[k * 2] = true;
                    _array[k * 2 + 1] = _operation(_array[k * 2 + 1], _array[k]);
                    flag[k * 2 + 1] = true;
                    _array[k] = _identity;
                }

                flag[k] = false;
            }
        }

        private void Update(int left, int right, int k, int l, int r, T item)
        {
            Eval(k, l, r);
            if (r <= left || right <= l)
            {
                return;
            }

            if (left <= l && r <= right)
            {
                _array[k] = _operation(_array[k], item);
                flag[k] = true;
                Eval(k, l, r);
                return;
            }

            Update(left, right, k * 2, l, (l + r) / 2, item);
            Update(left, right, k * 2 + 1, (l + r) / 2, r, item);
        }

        /// <summary> 
        /// [left,right)をoperation(A[i],item)に更新
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="item"></param>
        public void Update(int left, int right, T item)
        {
            Update(left, right, 1, 0, N, item);
        }


        /// <summary>
        /// A[i]を取得 O(log N)
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public T Get(int i)
        {
            int l = 0;
            int r = N;
            int k = 1;
            while (r - l > 1)
            {
                Eval(k, l, r);
                int m = (l + r) / 2;
                if (i < m)
                {
                    r = m;
                    k = k * 2;
                }
                else
                {
                    l = m;
                    k = k * 2 + 1;
                }
            }

            return _array[k];
        }

        public T this[int i]
        {
            get { return Get(i); }
        }
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(' ');
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}
0