二以上 -
タイトルのチェーン外で爆発する星の数を反映するために神々がありますが、私はフェンウィックツリーの増加章を通して一枚での翻訳がある場合は、マップについてあなたに固執することを決めたが、また、いくつかの中国の文法エラーを修正しました
この神々は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 。 }
トピックもっと楽しいがあります。
一般的な意味の質問あなたの星の座標を与えることである、星が(左とダウンしているされているを含む)星の左下に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 完事~