AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC410-C Rotatable Array


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("5 5");
            WillReturn.Add("2 3");
            WillReturn.Add("1 2 1000000");
            WillReturn.Add("3 4");
            WillReturn.Add("2 2");
            WillReturn.Add("2 3");
            //3
            //1
            //1000000
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("1000000 2");
            WillReturn.Add("1 1000000 999999");
            WillReturn.Add("3 1000000000");
            //
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        long[] wkArr = { };
        Action<string> SplitAct = pStr =>
            wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();

        SplitAct(InputList[0]);
        long N = wkArr[0];

        var ValDict = new Dictionary<long, long>();
        for (long I = 1; I <= N; I++) {
            ValDict[I] = I;
        }
        long BaseInd = 1;

        foreach (string EachStr in InputList.Skip(1)) {
            SplitAct(EachStr);
            long Type = wkArr[0];
            if (Type == 1) {
                long P = wkArr[1];
                long X = wkArr[2];
                long Target = BaseInd + P - 1;
                //while (Target > N) { Target -= N; }
                if ((Target %= N) == 0) Target = N;
                ValDict[Target] = X;
            }
            if (Type == 2) {
                long P = wkArr[1];
                long Target = BaseInd + P - 1;
                //while (Target > N) { Target -= N; }
                if ((Target %= N) == 0) Target = N;
                Console.WriteLine(ValDict[Target]);
            }
            if (Type == 3) {
                long K = wkArr[1];
                BaseInd += K;
                //while (BaseInd > N) { BaseInd -= N; }
                if ((BaseInd %= N) == 0) BaseInd = N;
            }
        }
    }
}


解説

配列の先頭位置をmodで考えてシュミレーションしてます。

modの計算は、
中学受験の日暦算で考えると分かりやすいです。
1日後の曜日
2日後の曜日
3日後の曜日
4日後の曜日
5日後の曜日
6日後の曜日
7日後の曜日
8日後の曜日は、1日後の曜日に等しい
9日後の曜日は、2日後の曜日に等しい

N日後の曜日は、下記のIF文で分かります。
if( ( N %= 7 ) == 0) { N = 7; }
このIF文を下記のWhile文で代用すると、値によってはTLEします。
While ( N < 7 ) { N -= 7; }