理解のフェンウィックツリー(接頭辞とし、差動)

二以上 -

タイトルのチェーン外で爆発する星の数を反映するために神々がありますが、私はフェンウィックツリーの増加章を通して一枚での翻訳がある場合は、マップについてあなたに固執することを決めたが、また、いくつかの中国の文法エラーを修正しました

 

この神々はKMPとハッシュを学んでいる、と私のこんにゃくはリーチツリーライングループを、学習する時間,,,,,だから私は、文字列アルゴリズムは、データ構造を修正することを決めた仕上げ後

この要約は、自分自身のために見ることが主なので、会場の原理とそのフェンウィックの木

彼は高いフアンみんなのブログ

この例では、主に

最初は、ボードの質問です

P3374 [テンプレート]フェンウィックの木1

問題は、ボードです

フェンウィックツリーの動作のいくつかを見てみましょう

1.特定のポイントに値を追加します。

ボイド更新(int型のx、int型のY)
{ 
    一方(X <= N){ 
        T [X] + = Y。
        X + = lowbit(X)。
    } 
}

検討フェンウィック木T [x]は区間[X-lowbit(X)+ 1、X]との間ですべての数を表し、及びアレイ2の全ての整数倍は2から前方の整数であるとして、Xが値Tであります貢献倍数は、私たちはすべてのlowbitを取る(x)はxの値を加算されます

あなたが読むことができない場合、あなたはこのマップを見ることができます

2.クエリの値の範囲があります

私たちは、確かに、このセクションの[X、Y]は(Y)-sum(X-1)権利を合計することである接頭辞の値を知っているし、我々はそれにSUM関数を記述する必要があります

INTの和(INT X)
{ 
    int型 RES = 0 一方、(X> 0 ){ 
        RES + = [X] T。
        X - = lowbit(X)。
    } 
    戻りRESと、
}

コード値は、すぐに(X)のlowbitを見つけることがあります

INT lowbit(INT X)
{ 
    戻り X&( - X)。
}

この道路ボードと、私たちはほとんどのタイトルで逃げます

コードを入れてください

書式#include <iostreamの> 
の#include <cstdioを>
 使用して 名前空間はstdを、
INTの N、M、T [ 500010 ]。
INT lowbit(INT X)
{ 
    戻り X&( - X)。
} 
ボイド更新(int型のx、int型のY)
{ 
    一方(X <= N){ 
        T [X] + = Y。
        X + = lowbit(X)。
    } 
} 
int型の和(INT X)
{ 
    int型 RES = 0 同時に(X> 0 ){ 
        RES + = T [X]。
        X - = lowbit(X)。
    } 
    戻りRESと、
} 
int型のmain()
{ 
    scanf関数(" %D%dの"、&​​N、&M)。
    以下のためにint型 iは= 1 ; iが<= N ++、V {I)
        のscanf(" %dの"、&V)。
        アップデート(I、V); 
    } 
    のためのint型 I = 1、TEMP、U、V、I <= M; ++ I){ 
        scanf関数("%D%D%D "&TEMP、&は、U、およびV);
         場合(TEMP == 1 )更新(U、V);
              のprintf(" %Dを\ n "、和(V) -和(uが- 1 )); 
    } 
    戻り 0 ; 
}

第二ボードを見てみましょう

P3368 [テンプレート]フェンウィックツリー2

質問のタイトル変更は、いくつかの数字を尋ねるとの差が、問われるので、私たちは、この要素の違いを追加します

乗算に従ってのlowbitとして又はにおけるpの元の意味は、[X]を示しなる[X X-lowbiut(X)+ 1]右端と間隔の左端との間の差を、(X)、私たちはこの合計を介して缶任意の数2の差分値を取得する機能は、その後、必要な番号を取得することができ引く、私が来て、ゆっくり話す言葉を理解していません。

第1の和と更新方法は同じですが、間隔の数のために私たちのすべては、zを追加し、その範囲内の差分値が変更されないため、我々は、右端のポイント差得点プラスZの唯一の左のポイントですライン上の位置の+1微分値-z

アップデート(L、Z)。
更新(R + 1、-z)。

差分値、すなわち合計(X)を得るためにすべての合計に直接的に特定の数は、この数を要求します

ビンそれに疑問

書式#include <iostreamの> 
の#include <cstdioを>
 使用して 名前空間はstdを、    
長い  N、M、T [ 500010 ]。
インラインINT lowbit(INT X)
{ 
    戻り X&( - X)。
}   
インラインボイド更新(int型のx、int型のY)
{ 
    一方(X <= N){ 
        T [X] + = Y。
        X + = lowbit(X)。
    } 
} 
インラインint型の和(int型X)
{
    int型のres = 0 ;
    一方、(X){ 
        RES + = T [X]。
        X - = lowbit(X)。
    } 
    戻りRESと、
} 
int型のmain()
{ 
    scanf関数(" %D%dの"、&​​N、&M)。
    INT今、過去= 0 ;
    以下のためにint型   i = 1 ; iは= N <; ++ I){ 
        scanf関数(" %のD "、&今)。
        アップデート(今私、 - 過去)。
        過去= 今; 
    } 
    のためにint型 I = 1、K、I <= M; ++ I){ 
        scanf関数(" %のD "、&K)。
        もし(Kの== 1 ){
             int型のX、Y、Z。
            scanf関数(" %D%D%D "、およびX&Y、およびZ)。
            アップデート(X、Z)。
            アップデート(Y + 1、 - Z)。
        } 
        {
             int型のX; 
            scanf関数(" %のD "、&x)は、
            printf(" %d個の\ n " 、SUM(X)); 
        } 
    } 
    戻り 0 
}

トピックもっと楽しいがあります。

ウラル1028星

 

一般的な意味の質問あなたの星の座標を与えることである、星が(左とダウンしているされているを含む)星の左下にk個を持って、これはK-クラスの星で、それぞれのレベルに星の数を聞いて、星の座標に従って昇順で入力したのと同じx軸によって昇順、y軸に入力されたy軸

 

私は2次元配列座標確かに最初にそれを思ったが、この場所でのデータの範囲であり、p [15000] [15000]あなたは確かに開いていないことができます参照してください、どのように言う必要があり、我々はこの質問を見て、彼の入力は素晴らしいああです星が含ま前に、入力を入力する必要があることを保証するために、私たちは辛いことができる[x]の横軸はxの星の数で表し使用して、実行し、再び統計を見ることができます

コード

この場所は、つまり、星の座標は、(0,0)のピットを持っているが、我々は接頭辞を実行し、そこlowbit(x)が運転するので、添字は1から開始しなければならないので、私たちそれぞれが読んだときに、すべての着信のx + +、そうではないだけで、最終的な結果には影響しませんが、パンはありません

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
using namespace std;
 
int c[32010];
int level[32010];
 
//求2的K次幂
int lowbit(int t)
{
    return t&(-t);
}
//更新树状数组
void update(int t)
{
    while(t<32010)
    {
        ++c[t];
        t+=lowbit(t);
    }
}
//获取前N项和
int getSum(int t)
{
    int sum = 0;
    while(t>0)
    {
        sum+=c[t];
        t-=lowbit(t);
    }
    return sum;
}
int main()
{
    int n;
    int x;
    int y;
    int i;
    int sum;
 
    scanf("%d",&n);
 
    memset(c,0,sizeof(c));
    memset(level,0,sizeof(c));
 
    for(i = 0;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        ++x;//星星的左边可以从0开始,但是update函数的参数却不能是0,所有向后移一位
        update(x);
        sum = getSum(x);
        ++level[sum];
    }
    for(i = 0;i<n;i++)
    {
        printf("%d\n",level[i+1]);
    }
    return 0;
}

ok 完事~

おすすめ

転載: www.cnblogs.com/this-is-M/p/11082874.html