ロステンプレートバレーP3368 [2]フェンウィック木(ツリーライン)

タイトル説明

それは、列の数にはよく知られている場合は、次の2つの操作を実行する必要があります。

各セクションに加えて、いくつかの数x 1

2.数の値を取得

入力形式

最初の行は、2つの整数N、Mを含み、それぞれの列と操作の回数の合計数の数を表します。

数が初期値のIアイテムのi番目の列を表す第2のラインは、スペースで区切られたN個の整数を含みます。

次のMラインが2又は4の整数を含んでいる次のように操作を示します。

操作1:フォーマット:1 XYK意味:区間[X、Y]各数k個プラス

操作2:フォーマット:2 xは意味:x値出力の数

出力フォーマット

出力は、すべて2の演算結果である線の整数を含んでいます。

サンプル入力と出力

入力#1
5 
1〜5 4 2 3 
1 2 4 2 
2 3 
1 1 5 -1 
1 3 5 7 
2 4
出力#1
6 
10

説明/ヒント

時間の制約:1000ミリ秒、128M

データスケール:

N <= 8、M <= 10:データの30%を

N <= 10000、M <= 10000:データの70%を

データの100%まで:N <= 500000、M <= 500000

サンプル説明:

したがって、出力は6,10です

書式#include <cstdioを> 
する#include <iostreamの> 
の#include <cmath> 
の#include < 文字列 > 
の#include <CStringの> 
の#include <アルゴリズム> 
書式#include <キュー> 
の#include <ベクトル> 
の#include <マップ>
 使用して 名前空間はstd; 

#defineは長い長いっ
 の#define EPS 1E-9 のconst int型 INF = 0x3f3f3f3f const int型 MOD = 1E9 + 7 INTの N、M、ANS、入力[ 500000 + 8 ]。

  



構造体ノード
{ 
    intです左、右、NUM; 
}ツリー[ 5000000 + 8 ]、

空洞ビルド(int型左、int型右、int型のインデックス)/// 寄与
{ 
    ツリー[インデックス] .nu​​m = 0 ; 
    ツリー[インデックス] .LEFT =は、左、
    ツリー[インデックス] .RIGHT = 右;
     IFは(左==右)/// ノードが葉である場合、値が彼返さ
        リターン;
     int型 MID =(左+右)/ 2 ; 
    ビルド(左、MIDを、インデックス *2); /// 左開始割り当て部から 
    ビルド(MID + 。1、右、インデックス* 2 + 1); /// 右区間開始割り当てから
} 

ボイド PLS(int型のインデックス、int型の L、int型の R&LT、INT K)/ // 区間kプラス値[L、R&LT] 
{
     IF(ツリー[インデックス] .LEFT>ツリー&& L = [インデックス] .RIGHT <= R&LT)/// 場合間隔内のオブジェクト範囲
    { 
        ツリー[インデックス] .nu​​m + = K;
         リターン; 
    } 
    IF(ツリー[指数* 2 ] .RIGHT> = L)/// ように、左プラス区間k
        PLS(指数* 2 、L、R&LT、K);
     IF(ツリー[指数* 2 + 1 ] .LEFT <= R&LT)/// ように右セクションプラスK 
        PLS(指数* 2 + 1 、L、R&LT、 K); 
} 

ボイド検索(int型のインデックス、INT DIS)/// その点を見つけ、そして彼の記録の値
{ 
    ANS +ツリー= [インデックス] .nu​​m; /// 記録動作後に増加/減少値
    IF(ツリー[インデックス] == .LEFT ツリー[インデックス] .RIGHT)
         リターン;
     IF(DIS <=ツリー[指数* 2 ] .RIGHT)/// この番号はインデックスポイント右息子よりも小さい場合、左に見つけます
        検索(インデックス* 2 、DIS);
     IF(DIS> =ツリー[インデックス* 2 + 1。 .LEFT])/// この数は、その後のために適切な外観に、左側の息子ポイントのインデックスよりも大きい場合には 
        検索(インデックス* 2 + 。1 、DIS); 
} 

int型のmain()
{ 
    scanfの(" %のD%のD "、およびN-、&M); 
    ビルド(1、N-、1。); /// 。初期化、開始の各々に割り当てられた値が1 
    のためのINT I = 1 ; I <= N; I ++ 
        scanfの(" %のD "、&入力[I])。
    以下のためにint型 iは= 1 ; iが<= M iは++ 
    { 
        int型
        scanf関数(" %のD "、&​​A )。
        もし(== 1 
        { 
            int型のX、Y、Z。
            scanf関数(" %D%D%D "、およびX&Y、およびZ)。
            PLS(1 、X、Y、Z)。
        } 
        そう であれば(== 2 
        { 
            ANS = 0 int型X; 
            scanfの(" %のD "、&x)は、
            検索(1、x)は; /// xをこの場所を見つけるためにルートから 
            のprintf(" %d個の\ N- "、ANS + INPUT [X]); 
        } 
    } 
    戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/RootVount/p/11278631.html