結果
| 問題 |
No.876 Range Compress Query
|
| コンテスト | |
| ユーザー |
keymoon
|
| 提出日時 | 2019-09-06 21:43:51 |
| 言語 | C#(csc) (csc 3.9.0) |
| 結果 |
AC
|
| 実行時間 | 950 ms / 2,000 ms |
| コード長 | 6,829 bytes |
| コンパイル時間 | 2,015 ms |
| コンパイル使用メモリ | 111,916 KB |
| 実行使用メモリ | 43,392 KB |
| 最終ジャッジ日時 | 2024-06-24 17:21:04 |
| 合計ジャッジ時間 | 10,723 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
コンパイルメッセージ
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.Net;
using System.Net.Sockets;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using static System.Math;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;
public static class P
{
public static void Main()
{
var nq = Console.ReadLine().Split().Select(int.Parse).ToArray();
var a = Console.ReadLine().Split().Select(int.Parse).ToArray();
SegmentTree<Segment, long> rcq =
new SegmentTree<Segment, long>
(
a.Select(x => new Segment() { Left = x, Right = x, Res = 1 }).ToArray(),
new Segment() { Left = -1, Right = -2, Res = 0 },
0,
Segment.Merge,
(x, y) => x + y,
(x, y) => new Segment() { Left = x.Left + y, Right = x.Right + y, Res = x.Res }
);
for (int i = 0; i < nq[1]; i++)
{
var query = Console.ReadLine().Split().Select(int.Parse).ToArray();
if (query[0] == 1)
{
rcq.Update(query[1] - 1, query[2] - 1, query[3]);
}
else
{
Console.WriteLine(rcq.Query(query[1] - 1, query[2] - 1).Res);
}
}
}
}
struct Segment
{
public long Left;
public int Res;
public long Right;
public static Segment Merge(Segment l, Segment r) => new Segment() { Left = l.Left, Res = l.Res + r.Res + (l.Right == r.Left ? -1 : 0), Right = r.Right };
}
class SegmentTree<DataT, OperatorT>
{
public readonly int Size;
DataT DataIdentity;
OperatorT OperatorIdentity;
Func<DataT, DataT, DataT> MergeData;
Func<OperatorT, OperatorT, OperatorT> MergeOperator;
Func<DataT, OperatorT, DataT> Operate;
int LeafCount;
int Height;
DataT[] Data;
OperatorT[] Operators;
#region Construct
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SegmentTree(int size, DataT dataIdentity, OperatorT operatorIdentity, Func<DataT, DataT, DataT> mergeData, Func<OperatorT, OperatorT, OperatorT> mergeOpeator, Func<DataT, OperatorT, DataT> operate)
: this(dataIdentity, operatorIdentity, mergeData, mergeOpeator, operate)
{
Size = size;
Build();
for (int i = 0; i < Data.Length; i++) Data[i] = DataIdentity;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public SegmentTree(DataT[] data, DataT dataIdentity, OperatorT operatorIdentity, Func<DataT, DataT, DataT> mergeData, Func<OperatorT, OperatorT, OperatorT> mergeOpeator, Func<DataT, OperatorT, DataT> operate)
: this(dataIdentity, operatorIdentity, mergeData, mergeOpeator, operate)
{
Size = data.Length;
Build();
for (int i = 0; i < data.Length; i++) Data[i + LeafCount] = data[i];
for (int i = data.Length + LeafCount; i < Data.Length; i++) Data[i] = dataIdentity;
for (int i = LeafCount - 1; i >= 0; i--) Data[i] = MergeData(Data[i << 1], Data[(i << 1) + 1]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private SegmentTree(DataT dataIdentity, OperatorT operatorIdentity, Func<DataT, DataT, DataT> mergeData, Func<OperatorT, OperatorT, OperatorT> mergeOpeator, Func<DataT, OperatorT, DataT> operate)
{
DataIdentity = dataIdentity;
OperatorIdentity = operatorIdentity;
MergeData = mergeData;
MergeOperator = mergeOpeator;
Operate = operate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Build()
{
Height = 1;
LeafCount = 1;
while (LeafCount < Size) { Height++; LeafCount <<= 1; }
Operators = new OperatorT[LeafCount << 1];
for (int i = 0; i < Operators.Length; i++) Operators[i] = OperatorIdentity;
Data = new DataT[LeafCount << 1];
}
#endregion
public DataT this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { Propagate(index + LeafCount); return Reflect(index); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { Propagate(index += LeafCount); Data[index] = value; Operators[index] = OperatorIdentity; Calculate(index, index); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(int l, int r, OperatorT x)
{
l += LeafCount;
r += LeafCount;
int origL = l, origR = r;
Propagate(l, r);
while (l <= r)
{
if ((l & 1) == 1) Operators[l] = MergeOperator(Operators[l], x);
if ((r & 1) == 0) Operators[r] = MergeOperator(Operators[r], x);
l = (l + 1) >> 1; r = (r - 1) >> 1;
}
Calculate(origL, origR);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public DataT Query(int l, int r)
{
l += LeafCount;
r += LeafCount;
DataT lRes = DataIdentity, rRes = DataIdentity;
Propagate(l, r);
while (l <= r)
{
if ((l & 1) == 1) lRes = MergeData(lRes, Reflect(l));
if ((r & 1) == 0) rRes = MergeData(Reflect(r), rRes);
l = (l + 1) >> 1; r = (r - 1) >> 1;
}
return MergeData(lRes, rRes);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Propagate(int ind) { for (int i = Height - 1; i >= 1; i--) { Eval(ind >> i); } return; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Propagate(int l, int r)
{
if (l == r) { Propagate(l); return; }
int xor = l ^ r, i = Height - 1;
for (; (xor >> i) == 0; i--) { Eval(l >> i); }
for (; i >= 1; i--) { Eval(l >> i); Eval(r >> i); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private DataT Reflect(int ind) { return Operate(Data[ind], Operators[ind]); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Eval(int ind)
{
int l = ind << 1, r = ind << 1 | 1;
Operators[l] = MergeOperator(Operators[l], Operators[ind]);
Operators[r] = MergeOperator(Operators[r], Operators[ind]);
Data[ind] = Reflect(ind);
Operators[ind] = OperatorIdentity;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Calculate(int l, int r)
{
var xor = l ^ r;
while (xor > 1) { xor >>= 1; l >>= 1; r >>= 1; Data[l] = MergeData(Reflect(l << 1), Reflect((l << 1) | 1)); Data[r] = MergeData(Reflect(r << 1), Reflect((r << 1) | 1)); }
while (l > 1) { l >>= 1; Data[l] = MergeData(Reflect(l << 1), Reflect((l << 1) | 1)); }
}
}
keymoon