結果
問題 |
No.3039 配信者
|
ユーザー |
![]() |
提出日時 | 2025-03-02 17:09:27 |
言語 | C#(csc) (csc 3.9.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 8,434 bytes |
コンパイル時間 | 4,580 ms |
コンパイル使用メモリ | 121,620 KB |
実行使用メモリ | 28,096 KB |
最終ジャッジ日時 | 2025-03-02 17:09:38 |
合計ジャッジ時間 | 9,440 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | TLE * 1 -- * 14 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
using System; using System.Collections.Generic; using System.Linq; // https://yukicoder.me/problems/no/3039 class Program { static string InputPattern = "InputX"; static List<string> GetInputList() { var WillReturn = new List<string>(); if (InputPattern == "Input1") { WillReturn.Add("3 5"); WillReturn.Add("0 2"); WillReturn.Add("1 4"); WillReturn.Add("2 3"); } else if (InputPattern == "Input2") { WillReturn.Add("7 10"); WillReturn.Add("8 9"); WillReturn.Add("3 6"); WillReturn.Add("2 4"); WillReturn.Add("1 8"); WillReturn.Add("7 9"); WillReturn.Add("0 4"); WillReturn.Add("5 6"); } 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 H = wkArr[1]; var InsLazySegmentTree = new LazySegmentTree(H, 0); foreach (string EachStr in InputList.Skip(1)) { SplitAct(EachStr); long A = wkArr[0]; long B = wkArr[1]; InsLazySegmentTree.Internal_RangeAdd(A, B, 1); } long Answer = InsLazySegmentTree.Internal_Query(0, H); Console.WriteLine(Answer); } } #region LazySegmentTree // LazySegmentTreeクラス (RMaxQ and RAQ) internal class LazySegmentTree { private long[] mTreeNodeArr; private long UB; // 木のノードの配列のUB private long mLeafCnt; // 葉ノードの数 private long mExternalArrUB; private long[] mLazyArr; // 遅延配列 // ノードの添字を引数とし、範囲の開始添字と終了添字を持つ配列 private struct RangeInfoDef { internal long StaInd; internal long EndInd; } private RangeInfoDef[] mRangeInfo; // ノードのIndexの列挙を返す internal IEnumerable<long> GetNodeIndEnum() { for (long I = 0; I <= mExternalArrUB; I++) { yield return I; } } // 木のノードのUBを返す internal long GetUB() { return mExternalArrUB; } // コンストラクタ internal LazySegmentTree(long pExternalArrUB, long pInitVal) { mExternalArrUB = pExternalArrUB; // 簡単のため、葉ノード数を2のべき乗に long ArrLength = 0; for (long I = 1; I < long.MaxValue; I *= 2) { ArrLength += I; mLeafCnt = I; if (pExternalArrUB + 1 < mLeafCnt) break; } // すべての値をpInitValに UB = ArrLength - 1; mTreeNodeArr = new long[UB + 1]; for (int I = 0; I <= UB; I++) { mTreeNodeArr[I] = pInitVal; } // 遅延配列を初期化 mLazyArr = new long[UB + 1]; // ノードの添字を引数とし、範囲の開始添字と終了添字を持つ配列の作成 mRangeInfo = new RangeInfoDef[UB + 1]; for (long I = 0; I <= UB; I++) { if (I == 0) { RangeInfoDef WillSet1; WillSet1.StaInd = 0; WillSet1.EndInd = mLeafCnt - 1; mRangeInfo[I] = WillSet1; continue; } long ParentNode = DeriveParentNode(I); RangeInfoDef ParentRangeInfo = mRangeInfo[ParentNode]; RangeInfoDef WillSet2; long Mid = (ParentRangeInfo.StaInd + ParentRangeInfo.EndInd) / 2; if (I % 2 == 1) { // 奇数ノードの場合 WillSet2.StaInd = ParentRangeInfo.StaInd; WillSet2.EndInd = Mid; } else { // 偶数ノードの場合 WillSet2.StaInd = Mid + 1; WillSet2.EndInd = ParentRangeInfo.EndInd; } mRangeInfo[I] = WillSet2; } } // 親ノードの添字を取得 private long DeriveParentNode(long pTarget) { return (pTarget - 1) / 2; } // 子ノードの添字(小さいほう)を取得 private long DeriveChildNode(long pTarget) { return pTarget * 2 + 1; } // 開始添字と終了添字とカレントノードを引数として、区間加算を行う internal void Internal_RangeAdd(long pSearchStaInd, long pSearchEndInd, long pAddVal) { Private_RangeAdd(pSearchStaInd, pSearchEndInd, pAddVal, 0); } private void Private_RangeAdd(long pSearchStaInd, long pSearchEndInd, long pAddVal, long pCurrNode) { // カレントノードの遅延評価を行う LazyEval(pCurrNode); long CurrNodeStaInd = mRangeInfo[pCurrNode].StaInd; long CurrNodeEndInd = mRangeInfo[pCurrNode].EndInd; // OverLapしてなければ、何もしない if (CurrNodeEndInd < pSearchStaInd || pSearchEndInd < CurrNodeStaInd) return; // 完全に含んでいれば、遅延配列に値を入れた後に評価 if (pSearchStaInd <= CurrNodeStaInd && CurrNodeEndInd <= pSearchEndInd) { mLazyArr[pCurrNode] += pAddVal; LazyEval(pCurrNode); return; } // そうでなければ、2つの区間に再帰呼出し long ChildNode1 = DeriveChildNode(pCurrNode); long ChildNode2 = ChildNode1 + 1; Private_RangeAdd(pSearchStaInd, pSearchEndInd, pAddVal, ChildNode1); Private_RangeAdd(pSearchStaInd, pSearchEndInd, pAddVal, ChildNode2); // カレントノードの更新 mTreeNodeArr[pCurrNode] = Math.Max(mTreeNodeArr[ChildNode1], mTreeNodeArr[ChildNode2]); } // 開始添字と終了添字とカレントノードを引数として、最大値を返す // 開始添字と終了添字とカレントノードを引数として、最大値を返す internal long Internal_Query(long pSearchStaInd, long pSearchEndInd) { return Private_Query(pSearchStaInd, pSearchEndInd, 0); } private long Private_Query(long pSearchStaInd, long pSearchEndInd, long pCurrNode) { // 該当ノードを遅延評価する LazyEval(pCurrNode); long CurrNodeStaInd = mRangeInfo[pCurrNode].StaInd; long CurrNodeEndInd = mRangeInfo[pCurrNode].EndInd; // OverLapしてなければ、long.MinValue if (CurrNodeEndInd < pSearchStaInd || pSearchEndInd < CurrNodeStaInd) return long.MinValue; // 完全に含んでいれば、このノードの値 if (pSearchStaInd <= CurrNodeStaInd && CurrNodeEndInd <= pSearchEndInd) return mTreeNodeArr[pCurrNode]; // そうでなければ、2つの子の最大値 long ChildNode1 = DeriveChildNode(pCurrNode); long ChildNode2 = ChildNode1 + 1; long ChildVal1 = Private_Query(pSearchStaInd, pSearchEndInd, ChildNode1); long ChildVal2 = Private_Query(pSearchStaInd, pSearchEndInd, ChildNode2); return Math.Max(ChildVal1, ChildVal2); } // カレントノードを引数として、遅延評価を行う private void LazyEval(long pCurrNode) { // 遅延配列が0なら何もしない if (mLazyArr[pCurrNode] == 0) return; // 遅延配列の値を設定する mTreeNodeArr[pCurrNode] += mLazyArr[pCurrNode]; long ChildNode1 = DeriveChildNode(pCurrNode); long ChildNode2 = ChildNode1 + 1; if (ChildNode1 <= UB) mLazyArr[ChildNode1] += mLazyArr[pCurrNode]; if (ChildNode2 <= UB) mLazyArr[ChildNode2] += mLazyArr[pCurrNode]; // 伝播が終わったので、自ノードの遅延配列を空にする mLazyArr[pCurrNode] = 0; } internal void DebugPrint() { for (long I = 0; I <= UB; I++) { if (mLazyArr[I] > 0) { Console.WriteLine("mTreeNodeArr[{0}] = {1} , mLazyArr[{0}] = {2}", I, mTreeNodeArr[I], mLazyArr[I]); } else { Console.WriteLine("mTreeNodeArr[{0}] = {1}", I, mTreeNodeArr[I]); } } } } #endregion