結果
問題 | No.259 セグメントフィッシング+ |
ユーザー | eitaho |
提出日時 | 2016-07-26 15:44:40 |
言語 | C#(csc) (csc 3.9.0) |
結果 |
AC
|
実行時間 | 1,140 ms / 2,000 ms |
コード長 | 12,077 bytes |
コンパイル時間 | 1,153 ms |
コンパイル使用メモリ | 120,060 KB |
実行使用メモリ | 75,092 KB |
最終ジャッジ日時 | 2024-11-06 17:00:07 |
合計ジャッジ時間 | 20,258 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 32 ms
27,044 KB |
testcase_01 | AC | 32 ms
24,876 KB |
testcase_02 | AC | 32 ms
26,916 KB |
testcase_03 | AC | 31 ms
25,136 KB |
testcase_04 | AC | 32 ms
24,860 KB |
testcase_05 | AC | 30 ms
25,140 KB |
testcase_06 | AC | 31 ms
27,304 KB |
testcase_07 | AC | 30 ms
24,840 KB |
testcase_08 | AC | 760 ms
72,908 KB |
testcase_09 | AC | 752 ms
74,952 KB |
testcase_10 | AC | 751 ms
74,820 KB |
testcase_11 | AC | 767 ms
74,820 KB |
testcase_12 | AC | 758 ms
75,092 KB |
testcase_13 | AC | 1,135 ms
74,312 KB |
testcase_14 | AC | 1,117 ms
72,136 KB |
testcase_15 | AC | 1,115 ms
74,428 KB |
testcase_16 | AC | 1,114 ms
74,560 KB |
testcase_17 | AC | 1,111 ms
72,520 KB |
testcase_18 | AC | 1,135 ms
72,516 KB |
testcase_19 | AC | 1,123 ms
74,188 KB |
testcase_20 | AC | 1,118 ms
72,264 KB |
testcase_21 | AC | 1,138 ms
72,404 KB |
testcase_22 | AC | 1,140 ms
74,312 KB |
testcase_23 | AC | 386 ms
49,544 KB |
testcase_24 | AC | 1,027 ms
74,824 KB |
testcase_25 | AC | 1,038 ms
72,772 KB |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
using System; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Collections.Generic; using System.Diagnostics; using System.Numerics; using Enu = System.Linq.Enumerable; public class Program { public void Solve() { int N = Reader.Int(), Q = Reader.Int(); int last = 0; var L = new Treap(); var R = new Treap(); L.Build(new long[N]); R.Build(new long[N]); Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }); foreach (var q in Reader.StringTable(Q)) { int t = int.Parse(q[1]), x = int.Parse(q[2]), y = int.Parse(q[3]); int diff = t - last; last = t; Treap.Node La, Lb, Ra, Rb; int mid = diff % N; Treap.Split(L.Root, mid, out La, out Lb); Treap.Split(R.Root, N - mid, out Ra, out Rb); if (diff / N % 2 == 0) { L.Root = Treap.Merge(Lb, Treap.Reverse(Rb)); R.Root = Treap.Merge(Treap.Reverse(La), Ra); } else { L.Root = Treap.Merge(Treap.Reverse(Ra), La); R.Root = Treap.Merge(Rb, Treap.Reverse(Lb)); } if (q[0] == "L") L[x] += y; else if (q[0] == "R") R[x] += y; else Console.WriteLine(L.Sum(x, y) + R.Sum(x, y)); } Console.Out.Flush(); } public class Treap { public Node Root; public class Node { static readonly Random random = new Random(0); public Node _L, _R; public int Count; public long Val; //public long RangeAdded; //public long Min; //public long Max; public long Sum; public bool Reversed; public readonly int Priority; public Node(long val) { Val = val; Count = 1; Priority = random.Next(); //Min = val; //Max = val; Sum = val; } public Node L { get { if (Reversed) PushDown(); return _L; } set { if (Reversed)PushDown(); _L = value; } } public Node R { get { if (Reversed) PushDown(); return _R; } set { if (Reversed) PushDown(); _R = value; } } public void PushDown() { //if (!Reversed && RangeAdded == 0) return; if (_L != null) { //_L.RangeAdded += RangeAdded; //_L.Min += RangeAdded; //_L.Max += RangeAdded; //_L.Sum += RangeAdded * _L.Count; _L.Reversed ^= Reversed; } if (_R != null) { //_R.RangeAdded += RangeAdded; //_R.Min += RangeAdded; //_R.Max += RangeAdded; //_R.Sum += RangeAdded * _R.Count; _R.Reversed ^= Reversed; } //if (Reversed) //{ var t = _L; _L = _R; _R = t; Reversed = false; //} //Val += RangeAdded; //RangeAdded = 0; Update(this); } public override string ToString() { return Val + (_L == null ? "" : " L:" + _L.Val) + (_R == null ? "" : " R:" + _R.Val); } } public void Build(long[] A, int L = 0, int R = -1) { Root = BuildRec(A, L, R == -1 ? A.Length : R); } Node BuildRec(long[] A, int L, int R) { if (R == -1) R = A.Length; if (R - L <= 0) return null; int mid = L + R >> 1; var node = new Node(A[mid]); node.L = BuildRec(A, L, mid); node.R = BuildRec(A, mid + 1, R); Update(node); return node; } public int Count { get { return Size(Root); } } static int Size(Node n) { return n == null ? 0 : n.Count; } static Node Update(Node n) { n.Count = 1 + (n._L == null ? 0 : n._L.Count) + (n._R == null ? 0 : n._R.Count); //n.Min = n.Val; //n.Max = n.Val; //if (n._L != null) //{ // n.Min = Math.Min(n.Min, n._L.Min); // n.Max = Math.Max(n.Max, n._L.Max); //} //if (n._R != null) //{ // n.Min = Math.Min(n.Min, n._R.Min); // n.Max = Math.Max(n.Max, n._R.Max); //} //n.Min += n.RangeAdded; //n.Max += n.RangeAdded; n.Sum = n.Val + /*n.RangeAdded * n.Count + */ (n._L == null ? 0 : n._L.Sum) + (n._R == null ? 0 : n._R.Sum); return n; } long RangeQuery(Node node, int L, int R, long init, Func<Node, long> nF, Func<long, long, long> F) { if (node == null || L >= R) return init; if (L == 0 && R == Size(node)) return nF(node); long res = init; int Lsize = Size(node.L); if (Lsize >= L && Lsize < R) res = node.Val; if (L < Lsize) res = F(res, RangeQuery(node.L, L, Math.Min(R, Lsize), init, nF, F)); if (R - Lsize - 1 > 0) res = F(res, RangeQuery(node.R, Math.Max(0, L - Lsize - 1), R - Lsize - 1, init, nF, F)); return res; } //public long Min(int L, int R) { return RangeQuery(Root, L, R, long.MaxValue, n => n.Min, Math.Min); } //public long Max(int L, int R) { return RangeQuery(Root, L, R, long.MinValue, n => n.Max, Math.Max); } public long Sum(int L, int R) { return RangeQuery(Root, L, R, 0, n => n.Sum, (a, b) => a + b); } //public void RangeAdd(int L, int R, long val) { RangeAdd(Root, L, R, val); } //void RangeAdd(Node node, int L, int R, long val) //{ // if (node == null || L >= R) return; // if (L == 0 && R == node.Count) // { // node.RangeAdded += val; // Update(node); // return; // } // int Lsize = Size(node.L); // if (Lsize >= L && Lsize < R) node.Val += val; // if (L < Lsize) RangeAdd(node.L, L, Math.Min(R, Lsize), val); // if (R - Lsize - 1 > 0) RangeAdd(node.R, Math.Max(0, L - Lsize - 1), R - Lsize - 1, val); // Update(node); //} public long this[int index] { get { Debug.Assert(index >= 0 && index < Size(Root)); var node = Root; while (index != Size(node.L)) if (index < Size(node.L)) node = node.L; else { index -= Size(node.L) + 1; node = node.R; } return node.Val; } set { if (index < Size(Root)) RemoveAt(index); Insert(index, value); } } public static Node Merge(Node L, Node R) { if (L == null) return R; if (R == null) return L; if (L.Priority > R.Priority) { L.R = Merge(L.R, R); return Update(L); } R.L = Merge(L, R.L); return Update(R); } public static void Split(Node n, int index, out Node L, out Node R) { if (n == null) { L = R = null; return; } Node a, b; if (index <= Size(n.L)) { Split(n.L, index, out a, out b); n.L = b; L = a; R = Update(n); } else { Split(n.R, index - Size(n.L) - 1, out a, out b); n.R = a; L = Update(n); R = b; } } public static void Split(Node n, int L, int R, out Node a, out Node b, out Node c) { Node t; Split(n, R, out t, out c); Split(t, L, out a, out b); } public void Insert(int index, long val) { Root = Insert(Root, new Node(val), index); } public Node Insert(Node node, Node newNode, int index) { if (node == null || index == Size(node.L) || newNode.Priority > node.Priority) { Node L, R; Split(node, index, out L, out R); node = Merge(L, newNode); node = Merge(node, R); } else { if (index < Size(node.L)) node.L = Insert(node.L, newNode, index); else node.R = Insert(node.R, newNode, index - Size(node.L) - 1); Update(node); } return node; } public void RemoveAt(int index) { Root = RemoveAt(Root, index); } Node RemoveAt(Node node, int index) { if (node == null || index == Size(node.L)) { Node L1, R1, L2, R2; Split(node, index, out L1, out R1); Split(R1, 1, out L2, out R2); node = Merge(L1, R2); } else { if (index < Size(node.L)) node.L = RemoveAt(node.L, index); else node.R = RemoveAt(node.R, index - Size(node.L) - 1); Update(node); } return node; } public void Reverse(int L, int R) { Root = Reverse(Root, L, R); } public static Node Reverse(Node node, int L = 0, int R = -1) { if (node == null) return null; if (R == -1) R = Size(node); Node a, b, c; Split(node, L, R, out a, out b, out c); b.Reversed ^= true; return Merge(a, Merge(b, c)); } } } class Entry { static void Main() { new Program().Solve(); } } class Reader { static TextReader reader = Console.In; static readonly char[] separator = { ' ' }; static readonly StringSplitOptions op = StringSplitOptions.RemoveEmptyEntries; static string[] A = new string[0]; static int i; static void Init() { A = new string[0]; } public static void Set(TextReader r) { reader = r; Init(); } public static void Set(string file) { reader = new StreamReader(file); Init(); } public static bool HasNext() { return CheckNext(); } public static string String() { return Next(); } public static int Int() { return int.Parse(Next()); } public static long Long() { return long.Parse(Next()); } public static double Double() { return double.Parse(Next()); } public static int[] IntLine() { return Array.ConvertAll(Split(Line()), int.Parse); } public static int[] IntArray(int N) { return Range(N, Int); } public static int[][] IntTable(int H) { return Range(H, IntLine); } public static string[] StringArray(int N) { return Range(N, Next); } public static string[][] StringTable(int N) { return Range(N, () => Split(Line())); } public static string Line() { return reader.ReadLine().Trim(); } static string[] Split(string s) { return s.Split(separator, op); } static T[] Range<T>(int N, Func<T> f) { var r = new T[N]; for (int i = 0; i < N; r[i++] = f()) ; return r; } static string Next() { CheckNext(); return A[i++]; } static bool CheckNext() { if (i < A.Length) return true; string line = reader.ReadLine(); if (line == null) return false; if (line == "") return CheckNext(); A = Split(line); i = 0; return true; } }