using System.Collections; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using static InputUtil; // VVVVVVVVVVV ここからコード VVVVVVVVVVV var n = ReadLine(); Console.WriteLine(n*n); // XXXXXXXXXXX ここまでコード XXXXXXXXXXXX #region library #pragma warning disable CA1050 /// /// 標準入力の読み取りを簡素化する機能を提供します。 /// public static class InputUtil { /// /// 標準入力からスペースで区切られた値を指定の型に変換して読み込みます。 /// /// /// 1つの値を読み込むには型を明示し int a = ReadLine<int>() のように書きます。 /// 定数個の値を読み取るには var (a, b, c) = ReadLine<int>(); のように書きます。 /// 可変個の値を読み取るには foreach (var item in ReadLine<int>()) のように書きます。 /// ToArray() メソッドや Linq も使えます。 /// /// 変換先の型 /// 標準入力の読み取り結果。 /// /// public static InputToken> ReadLine() where T : ISpanParsable { return new InputToken>(Console.ReadLine() ?? throw new InvalidOperationException()); } /// /// 標準入力から指定の文字で区切られた値を指定の型に変換して読み込みます。 /// 使用方法は を参照してください。 /// /// /// /// /// /// public static InputToken> ReadLine(IFormatProvider formatProvider, char separator) where T : ISpanParsable { return new InputToken>(Console.ReadLine() ?? throw new InvalidOperationException(), formatProvider, separator); } /// /// 標準入力からスペースで区切られた文字列を読み込みます。 /// 使用方法は を参照してください。 /// /// /// public static InputToken ReadLine() { return new InputToken(Console.ReadLine() ?? throw new InvalidOperationException()); } /// /// 標準入力から指定の文字で区切られた文字列を読み込みます。 /// 使用方法は を参照してください。 /// /// /// /// /// public static InputToken ReadLine(IFormatProvider formatProvider, char separator) { return new InputToken(Console.ReadLine() ?? throw new InvalidOperationException(), formatProvider, separator); } } public interface IReadNextValueImpl { public static abstract TResult ReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider); public static abstract bool TryReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider, out TResult value); } public readonly struct SpanParsableImpl : IReadNextValueImpl where T : ISpanParsable { public static T ReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider) { ReadOnlySpan span = input.AsSpan()[currentIndex..]; var index = span.IndexOf(separator); ReadOnlySpan target = index == -1 ? span : span[..index]; if (target.Length == 0) { ThrowSeparatorNotFound(); } var value = T.Parse(target, formatProvider); currentIndex = index == -1 ? input.Length : currentIndex + index + 1; return value; } private static void ThrowSeparatorNotFound() { throw new FormatException($"Separator not found"); } public static bool TryReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider, out T value) { ReadOnlySpan span = input.AsSpan()[currentIndex..]; var index = span.IndexOf(separator); ReadOnlySpan target = index == -1 ? span : span[..index]; if (target.Length == 0) { value = default!; return false; } value = T.Parse(target, formatProvider); currentIndex = index == -1 ? input.Length : currentIndex + index + 1; return true; } } public readonly struct StringImpl : IReadNextValueImpl { public static string ReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider) { ReadOnlySpan span = input.AsSpan()[currentIndex..]; var index = span.IndexOf(separator); ReadOnlySpan target = index == -1 ? span : span[..index]; if (target.Length == 0) { ThrowSeparatorNotFound(); } var value = target.ToString(); currentIndex = index == -1 ? input.Length : currentIndex + index + 1; return value; } private static void ThrowSeparatorNotFound() { throw new FormatException($"Separator not found"); } public static bool TryReadNextValue(string input, ref int currentIndex, char separator, IFormatProvider formatProvider, out string value) { ReadOnlySpan span = input.AsSpan()[currentIndex..]; var index = span.IndexOf(separator); ReadOnlySpan target = index == -1 ? span : span[..index]; if (target.Length == 0) { value = default!; return false; } value = target.ToString(); currentIndex = index == -1 ? input.Length : currentIndex + index + 1; return true; } } public struct InputToken : IEnumerable, IEnumerator where TImpl : IReadNextValueImpl { private readonly string _input; private int _currentIndex; private readonly IFormatProvider _formatProvider; private readonly char _separator; #pragma warning disable CS8618 // Property Current is initialized in MoveNext public InputToken(string input) { _input = input; _formatProvider = System.Globalization.CultureInfo.InvariantCulture; _separator = ' '; } public InputToken(string input, IFormatProvider formatProvider, char separator) { _input = input; _formatProvider = formatProvider; _separator = separator; } #pragma warning restore CS8618 public static implicit operator TResult(InputToken token) { return token.ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2) { val1 = ReadNextValue(); val2 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3, out TResult val4) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); val4 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3, out TResult val4, out TResult val5) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); val4 = ReadNextValue(); val5 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3, out TResult val4, out TResult val5, out TResult val6) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); val4 = ReadNextValue(); val5 = ReadNextValue(); val6 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3, out TResult val4, out TResult val5, out TResult val6, out TResult val7) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); val4 = ReadNextValue(); val5 = ReadNextValue(); val6 = ReadNextValue(); val7 = ReadNextValue(); } public void Deconstruct(out TResult val1, out TResult val2, out TResult val3, out TResult val4, out TResult val5, out TResult val6, out TResult val7, out TResult val8) { val1 = ReadNextValue(); val2 = ReadNextValue(); val3 = ReadNextValue(); val4 = ReadNextValue(); val5 = ReadNextValue(); val6 = ReadNextValue(); val7 = ReadNextValue(); val8 = ReadNextValue(); } private TResult ReadNextValue() { return TImpl.ReadNextValue(_input, ref _currentIndex, _separator, _formatProvider); } public readonly InputToken GetEnumerator() { return this; } public TResult Current { get; private set; } readonly object IEnumerator.Current => Current!; public bool MoveNext() { var val = TImpl.TryReadNextValue(_input, ref _currentIndex, _separator, _formatProvider, out TResult? current); Current = current; return val; } public TResult[] ToArray() { if (_input.Length == 0) { return Array.Empty(); } ref var begin = ref Unsafe.As(ref MemoryMarshal.GetReference(_input.AsSpan())); var count = SpanHelpers.CountValueType(ref begin, _separator, _input.Length) + (_input[^1] == _separator ? 0 : 1); var array = new TResult[count]; for (var i = 0; i < array.Length; i++) { array[i] = ReadNextValue(); } return array; } readonly IEnumerator IEnumerable.GetEnumerator() { return this; } readonly IEnumerator IEnumerable.GetEnumerator() { return this; } void IEnumerator.Reset() { _currentIndex = 0; } readonly void IDisposable.Dispose() { } } // Source: [System.Private.CoreLib]System.SpanHelpers internal static class SpanHelpers { public static int CountValueType(ref T current, T value, int length) where T : struct, IEquatable? { var count = 0; ref T end = ref Unsafe.Add(ref current, length); if (Vector128.IsHardwareAccelerated && length >= Vector128.Count) { // Vector512 is not supported on .NET 7.0 so Vector512 code is not included. if (Vector256.IsHardwareAccelerated && length >= Vector256.Count) { var targetVector = Vector256.Create(value); ref T oneVectorAwayFromEnd = ref Unsafe.Subtract(ref end, Vector256.Count); do { count += BitOperations.PopCount(Vector256.Equals(Vector256.LoadUnsafe(ref current), targetVector).ExtractMostSignificantBits()); current = ref Unsafe.Add(ref current, Vector256.Count); } while (!Unsafe.IsAddressGreaterThan(ref current, ref oneVectorAwayFromEnd)); // If there are just a few elements remaining, then processing these elements by the scalar loop // is cheaper than doing bitmask + popcount on the full last vector. To avoid complicated type // based checks, other remainder-count based logic to determine the correct cut-off, for simplicity // a half-vector size is chosen (based on benchmarks). var remaining = (uint)Unsafe.ByteOffset(ref current, ref end) / (uint)Unsafe.SizeOf(); if (remaining > Vector256.Count / 2) { var mask = Vector256.Equals(Vector256.LoadUnsafe(ref oneVectorAwayFromEnd), targetVector).ExtractMostSignificantBits(); // The mask contains some elements that may be double-checked, so shift them away in order to get the correct pop-count. var overlaps = (uint)Vector256.Count - remaining; mask >>= (int)overlaps; count += BitOperations.PopCount(mask); return count; } } else { var targetVector = Vector128.Create(value); ref T oneVectorAwayFromEnd = ref Unsafe.Subtract(ref end, Vector128.Count); do { count += BitOperations.PopCount(Vector128.Equals(Vector128.LoadUnsafe(ref current), targetVector).ExtractMostSignificantBits()); current = ref Unsafe.Add(ref current, Vector128.Count); } while (!Unsafe.IsAddressGreaterThan(ref current, ref oneVectorAwayFromEnd)); var remaining = (uint)Unsafe.ByteOffset(ref current, ref end) / (uint)Unsafe.SizeOf(); if (remaining > Vector128.Count / 2) { var mask = Vector128.Equals(Vector128.LoadUnsafe(ref oneVectorAwayFromEnd), targetVector).ExtractMostSignificantBits(); // The mask contains some elements that may be double-checked, so shift them away in order to get the correct pop-count. var overlaps = (uint)Vector128.Count - remaining; mask >>= (int)overlaps; count += BitOperations.PopCount(mask); return count; } } } while (Unsafe.IsAddressLessThan(ref current, ref end)) { if (current.Equals(value)) { count++; } current = ref Unsafe.Add(ref current, 1); } return count; } } #endregion