提出 #28443341
ソースコード 拡げる
using System;
using System.Collections.Generic;
using System.Linq;
// https://atcoder.jp/contests/past201912-open/tasks/past201912_h
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("4");
WillReturn.Add("5 3 3 5");
WillReturn.Add("6");
WillReturn.Add("1 2 1");
WillReturn.Add("2 2");
WillReturn.Add("2 2");
WillReturn.Add("3 100");
WillReturn.Add("3 1");
WillReturn.Add("1 1 3");
//9
}
else if (InputPattern == "Input2") {
WillReturn.Add("10");
WillReturn.Add("241 310 105 738 405 490 158 92 68 20");
WillReturn.Add("20");
WillReturn.Add("2 252");
WillReturn.Add("1 4 36");
WillReturn.Add("2 69");
WillReturn.Add("1 5 406");
WillReturn.Add("3 252");
WillReturn.Add("1 3 8");
WillReturn.Add("1 10 10");
WillReturn.Add("3 11");
WillReturn.Add("1 4 703");
WillReturn.Add("3 1");
WillReturn.Add("2 350");
WillReturn.Add("3 10");
WillReturn.Add("2 62");
WillReturn.Add("2 3");
WillReturn.Add("2 274");
WillReturn.Add("1 2 1");
WillReturn.Add("3 126");
WillReturn.Add("1 4 702");
WillReturn.Add("3 6");
WillReturn.Add("2 174");
//390
}
else if (InputPattern == "Input3") {
WillReturn.Add("2");
WillReturn.Add("3 4");
WillReturn.Add("3");
WillReturn.Add("1 2 9");
WillReturn.Add("2 4");
WillReturn.Add("3 4");
//0
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long N = int.Parse(InputList[0]);
long[] CArr = InputList[1].Split(' ').Select(X => long.Parse(X)).ToArray();
var LazySegmentTree_IndOdd = new LazySegmentTree(N);
var LazySegmentTree_IndEven = new LazySegmentTree(N);
long MaxCVal = CArr.Max();
long OddCnt = 0;
long EvenCnt = 0;
for (long I = 0; I <= CArr.GetUpperBound(0); I++) {
if (I % 2 == 0) {
LazySegmentTree_IndEven.RangeAdd(I, I, CArr[I], 0);
LazySegmentTree_IndOdd.RangeAdd(I, I, MaxCVal, 0);
EvenCnt++;
}
else {
LazySegmentTree_IndEven.RangeAdd(I, I, MaxCVal, 0);
LazySegmentTree_IndOdd.RangeAdd(I, I, CArr[I], 0);
OddCnt++;
}
}
long Answer = 0;
foreach (string EachStr in InputList.Skip(3)) {
long[] SplitArr = EachStr.Split(' ').Select(X => long.Parse(X)).ToArray();
if (SplitArr[0] == 1) {
long X = SplitArr[1] - 1;
long C = SplitArr[2];
long CurrCnt;
LazySegmentTree wkP;
if (X % 2 == 0) {
wkP = LazySegmentTree_IndEven;
}
else {
wkP = LazySegmentTree_IndOdd;
}
CurrCnt = wkP.Query(X, X, 0);
if (CurrCnt >= C) {
wkP.RangeAdd(X, X, -C, 0);
Answer += C;
}
}
if (SplitArr[0] == 2) {
long C = SplitArr[1];
long MinCnt = LazySegmentTree_IndEven.Query(0, N - 1, 0);
if (MinCnt >= C) {
LazySegmentTree_IndEven.RangeAdd(0, N - 1, -C, 0);
Answer += C * EvenCnt;
}
}
if (SplitArr[0] == 3) {
long C = SplitArr[1];
long MinCnt1 = LazySegmentTree_IndEven.Query(0, N - 1, 0);
long MinCnt2 = LazySegmentTree_IndOdd.Query(0, N - 1, 0);
if (MinCnt1 >= C && MinCnt2 >= C) {
LazySegmentTree_IndEven.RangeAdd(0, N - 1, -C, 0);
LazySegmentTree_IndOdd.RangeAdd(0, N - 1, -C, 0);
Answer += C * EvenCnt;
Answer += C * OddCnt;
}
}
}
Console.WriteLine(Answer);
}
}
#region LazySegmentTree
// LazySegmentTreeクラス (RMQ and RAQ)
internal class LazySegmentTree
{
private long[] mTreeNodeArr;
private long UB; // 木のノードの配列のUB
private long mLeafCnt; // 葉ノードの数
private long[] mLazyArr; // 遅延配列
// ノードの添字を引数とし、範囲の開始添字と終了添字を持つ配列
private struct RangeInfoDef
{
internal long StaInd;
internal long EndInd;
}
private RangeInfoDef[] mRangeInfo;
// コンストラクタ
internal LazySegmentTree(long pLeafCnt)
{
// 簡単のため、葉ノード数を2のべき乗に
long ArrLength = 0;
for (long I = 1; I < long.MaxValue; I *= 2) {
ArrLength += I;
mLeafCnt = I;
if (pLeafCnt < mLeafCnt) break;
//if (pLeafCnt <= mLeafCnt) break;
}
// すべての値を0に
UB = ArrLength - 1;
mTreeNodeArr = new long[UB + 1];
for (int I = 0; I <= UB; I++) {
mTreeNodeArr[I] = 0;
}
// 遅延配列を初期化
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 RangeAdd(long pSearchStaInd, long pSearchEndInd, long pUpdateVal, 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] += pUpdateVal * (CurrNodeEndInd - CurrNodeStaInd + 1);
mLazyArr[pCurrNode] += pUpdateVal;
LazyEval(pCurrNode);
return;
}
// そうでなければ、2つの区間に再帰呼出し
long ChildNode1 = DeriveChildNode(pCurrNode);
long ChildNode2 = ChildNode1 + 1;
RangeAdd(pSearchStaInd, pSearchEndInd, pUpdateVal, ChildNode1);
RangeAdd(pSearchStaInd, pSearchEndInd, pUpdateVal, ChildNode2);
// カレントノードの更新
mTreeNodeArr[pCurrNode] = Math.Min(mTreeNodeArr[ChildNode1], mTreeNodeArr[ChildNode2]);
}
// 開始添字と終了添字とカレントノードを引数として、最小値を返す
internal long Query(long pSearchStaInd, long pSearchEndInd, long pCurrNode)
{
// 該当ノードを遅延評価する
LazyEval(pCurrNode);
long CurrNodeStaInd = mRangeInfo[pCurrNode].StaInd;
long CurrNodeEndInd = mRangeInfo[pCurrNode].EndInd;
// OverLapしてなければ、int.MaxValue
if (CurrNodeEndInd < pSearchStaInd || pSearchEndInd < CurrNodeStaInd)
return int.MaxValue;
// 完全に含んでいれば、このノードの値
if (pSearchStaInd <= CurrNodeStaInd && CurrNodeEndInd <= pSearchEndInd)
return mTreeNodeArr[pCurrNode];
// そうでなければ、2つの子の最小値
long ChildNode1 = DeriveChildNode(pCurrNode);
long ChildNode2 = ChildNode1 + 1;
long ChildVal1 = Query(pSearchStaInd, pSearchEndInd, ChildNode1);
long ChildVal2 = Query(pSearchStaInd, pSearchEndInd, ChildNode2);
return Math.Min(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
提出情報
| 提出日時 |
|
| 問題 |
H - まとめ売り |
| ユーザ |
aketijyuuzou |
| 言語 |
C# (.NET Core 3.1.201) |
| 得点 |
6 |
| コード長 |
10990 Byte |
| 結果 |
AC |
| 実行時間 |
588 ms |
| メモリ |
100180 KiB |
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
6 / 6 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
example_01.txt, example_02.txt, example_03.txt |
| All |
example_01.txt, example_02.txt, example_03.txt, subtask_01_01.txt, subtask_01_02.txt, subtask_01_03.txt, subtask_01_04.txt, subtask_01_05.txt, subtask_01_06.txt, subtask_01_07.txt, subtask_01_08.txt, subtask_01_09.txt, subtask_01_10.txt, subtask_01_11.txt, subtask_01_12.txt, subtask_01_13.txt, subtask_01_14.txt, subtask_01_15.txt, subtask_01_16.txt, subtask_01_17.txt, subtask_01_18.txt, subtask_01_19.txt, subtask_01_20.txt, subtask_01_21.txt, subtask_01_22.txt, subtask_01_23.txt, subtask_01_24.txt, subtask_01_25.txt, subtask_01_26.txt, subtask_01_27.txt, subtask_01_28.txt, subtask_01_29.txt, subtask_01_30.txt, subtask_01_31.txt, subtask_01_32.txt, subtask_01_33.txt, subtask_01_34.txt, subtask_01_35.txt, subtask_01_36.txt, subtask_01_37.txt, subtask_01_38.txt, subtask_01_39.txt, subtask_01_40.txt, subtask_01_41.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| example_01.txt |
AC |
90 ms |
27960 KiB |
| example_02.txt |
AC |
82 ms |
28004 KiB |
| example_03.txt |
AC |
78 ms |
28032 KiB |
| subtask_01_01.txt |
AC |
90 ms |
28020 KiB |
| subtask_01_02.txt |
AC |
83 ms |
28260 KiB |
| subtask_01_03.txt |
AC |
496 ms |
99964 KiB |
| subtask_01_04.txt |
AC |
482 ms |
99948 KiB |
| subtask_01_05.txt |
AC |
482 ms |
99892 KiB |
| subtask_01_06.txt |
AC |
499 ms |
100016 KiB |
| subtask_01_07.txt |
AC |
482 ms |
100072 KiB |
| subtask_01_08.txt |
AC |
588 ms |
96800 KiB |
| subtask_01_09.txt |
AC |
484 ms |
96708 KiB |
| subtask_01_10.txt |
AC |
487 ms |
99740 KiB |
| subtask_01_11.txt |
AC |
486 ms |
99124 KiB |
| subtask_01_12.txt |
AC |
454 ms |
100180 KiB |
| subtask_01_13.txt |
AC |
455 ms |
100036 KiB |
| subtask_01_14.txt |
AC |
457 ms |
100108 KiB |
| subtask_01_15.txt |
AC |
460 ms |
99688 KiB |
| subtask_01_16.txt |
AC |
440 ms |
99840 KiB |
| subtask_01_17.txt |
AC |
467 ms |
100152 KiB |
| subtask_01_18.txt |
AC |
451 ms |
99880 KiB |
| subtask_01_19.txt |
AC |
575 ms |
99848 KiB |
| subtask_01_20.txt |
AC |
563 ms |
99020 KiB |
| subtask_01_21.txt |
AC |
525 ms |
99816 KiB |
| subtask_01_22.txt |
AC |
522 ms |
100044 KiB |
| subtask_01_23.txt |
AC |
524 ms |
99600 KiB |
| subtask_01_24.txt |
AC |
519 ms |
99744 KiB |
| subtask_01_25.txt |
AC |
524 ms |
99968 KiB |
| subtask_01_26.txt |
AC |
475 ms |
99648 KiB |
| subtask_01_27.txt |
AC |
491 ms |
99240 KiB |
| subtask_01_28.txt |
AC |
446 ms |
99684 KiB |
| subtask_01_29.txt |
AC |
461 ms |
99692 KiB |
| subtask_01_30.txt |
AC |
467 ms |
99804 KiB |
| subtask_01_31.txt |
AC |
451 ms |
100056 KiB |
| subtask_01_32.txt |
AC |
450 ms |
99572 KiB |
| subtask_01_33.txt |
AC |
453 ms |
99664 KiB |
| subtask_01_34.txt |
AC |
448 ms |
99716 KiB |
| subtask_01_35.txt |
AC |
486 ms |
99828 KiB |
| subtask_01_36.txt |
AC |
482 ms |
99180 KiB |
| subtask_01_37.txt |
AC |
466 ms |
100164 KiB |
| subtask_01_38.txt |
AC |
498 ms |
99776 KiB |
| subtask_01_39.txt |
AC |
467 ms |
99728 KiB |
| subtask_01_40.txt |
AC |
470 ms |
99808 KiB |
| subtask_01_41.txt |
AC |
475 ms |
99928 KiB |