2633. [HZOI 2016]シーケンス動作電子
★★★☆入力ファイル:rneaty.in
出力ファイル:rneaty.out
の単純な比較
制限時間:1秒メモリ制限:128メガバイト
説明[タイトル]
長さnの配列、開始配列の加重値は0であり、mは動作を有します
これは、2つの動作モードをサポートしています
区間[L、R]、プラス最初の数X、第二の数プラス1 LR Xを、2 2 ⋅ X、プラス第3の数。3 2 ⋅ Xの数の... R-L + 1プラス(R&LT - Lの+ 1 )2 ⋅ X
重量で2 LRクエリ区間[L、R]
たび問い合わせへの回答2 64を法
[入力形式]
2点の数N、Mの最初の行は、配列の長さおよび操作の数を表します。
続いて行をM、各列は、操作、次の2つの状況を示します。
区間[L、R]、プラス最初の数X、第二の数プラス1 LR Xを、2 2 ⋅ X、プラス第3の数。3 2 ⋅ Xの数の... R-L + 1プラス(R&LT - Lの+ 1 )2 ⋅ X
重量で2 LRクエリ区間[L、R]
[出力形式]
出力を減少させるために、あなただけの出力にするすべての答え必要な2 64をフィルムが取られ、XORされた後。
[サンプル入力]
5 5
1 3 4 1
2 1 5
2 2 2
1 3 3 1
1 2 4 1
[サンプル出力]
5
[注]
データNの10%、M <= 2000
データnの30%、M <= 10000
データの100%を、N-、M <= 100000,1 <= L <= R&LT <= N、0 <= X <= 10 。9
[ソース]
名前が非常に長いこんにゃくです
永久的なマーカーセグメントツリーQAQ
この方法は、オープン式での質問の第一の主題であります
これは、最終的に分割することができる:I ^ 2 * X + I * 2(1-L)* X +(L-1)^ 2 * X
その後、我々はLZをマークし、すべてのために戦います
同時に、いくつかのもの最初の前処理
最初の例では、I ^ 2前処理することができます
第二項は、iが2 *(1-L)*前処理することができます
第三は、(L-1)^ 2 //事実、無前処理前処理することができます
私たちは、より簡単な式の後にオープン分割しました
いくつかの補完的な知識があります。
2 ^ 64を自動的にモジュロれる長い長い1.unsigned
2. I ^ 2 iは*私の仕事(それ以外の場合は30点)1ull *になるように爆発的intQAQの種類を防ぐために注意を払うようにしてください
コードは以下の通りです
:
♪(^∇^ *)
#include <ビット/ STDC ++ H> の#define MAXN 100005 の#define LL符号なし長い長 の#define半ば(L + R >> 1) 使用して 名前空間STDを、 INTのN、M。 int型RT; int型の CNT; // 标记下标 INT LS [MAXN << 1 ]、RS [MAXN << 1 ]。 【MAXN lz0 LL << 1 ]、LZ1 [MAXN << 1 ]、LZ2 [MAXN << 1 ]。 LL和[MAXN << 1 ]。 LLのS1 [MAXN]、S2 [MAXN]。 無効ビルド(INT&RT、int型の L、int型R) { もし!(RT) RT = ++ CNT。 もし(L == R)の リターン; (LS [RT]、L、中間)を構築します。 ビルド(RS [RT]、ミッド + 1 、R)。 } LL ANS。 ボイド追加(INT RT、INT L、INT R、int型の、INT T、LL×2、LL×1、LLのX0) { 場合(S> R || T < L)の リターン; もし(S <= 1 && R <= T) { LZ2 [RT] + = X2。 LZ1 [RT] + = X1。 lz0 [RT] + = X0。 和[RT] =和[LS [RT] +和[RS [RT] + LZ2 [RT] *(S2 [R] -S2 [1- 1 ])+ LZ1 [RT] *(S1 [R] -S1 [1- 1 ])+ lz0 [RT】*(R-L + 1 )。 返します。 } (LS [RT]、L、中間、S、T、X2、X1、X0)を加えます。 (RS [RT]、ミッド追加 + 1 、R、S、T、X2、X1、X0)。 和[RT] =和[LS [RT] +和[RS [RT] + LZ2 [RT] *(S2 [R] -S2 [1- 1 ])+ LZ1 [RT] *(S1 [R] -S1 [1- 1 ])+ lz0 [RT] *(R-L + 1 )。 返します。 } LL和(int型 RT、int型L、 INTR、INT S、INT T) { 場合(S> R || T < L) 戻り 0 ; もし(S <= 1 && R <= T) 戻り和[RT]。 INT LL = MAX(L、S)。 INT RR = 分(R、T)。 戻り合計(LS [RT]、L、中間、S、T)+合計(RS [RT]、ミッド+ 1、R、S、T)+ LZ2 [RT] *(S2 [RR] -S2 [LL- 1 ])+ LZ1 [RT] *(S1 [RR] -S1 [LL- 1 ])+ lz0 [RT] *(RR-LL + 1 )。 } int型のmain() { freopenは(" rneaty.in "、「R"STDIN); freopenは(" rneaty.out " " W "STDOUT); scanf関数(" %d個の%のD "、&N、&;)M (RT、ビルド1 、N) のための(INT I = 1 ; I <= N; iが++ ) { S1 [i]は = S1 [I- 1 ] + I、 S2 [i]は = S2 [I- 1 ] + I *は1ull * iが; } ながら(M-- ) { int型、L、Rを選ぶ; scanf関数(" %D%D%D "およびオプトイン、&L&R); 場合(OPTの== 1 ) { ; LLのX のscanf(" %のLLU 」、およびX); // iは^ 2 * X + iが(2 * 1-L)* X +(L-1)^ 2 * X // 1 ^ 2 + 2 ^ 2 + 3 ^ 2 + ... + N ^ 2 = N *(N + 1)×(2N + 1) / 6 の追加(1、1、N、L、R、X、X * 2 *(1ull-L)、(L- 1)* X *(L- 1 )); } そう ANS ^ =合計(1、1 、N、L、R); } のprintf(" %LLUする\ n " 、ANS)。 リターン 0 ; }