以下のような複数のツリーの固定された配列の全長
アウトライン
時々、私たちはツリー状の配列の多くを必要とし、それらのそれぞれは、大きなサイズの範囲をしているが、全体の長さは固定されており、大きすぎではありません。
この時点で、我々はすべてのフェンウィックツリー順序は、アレイの上に配置されることができ、それらのそれぞれは、通常のビットに基づいて作成する出発点から、標準的なサイズの配列のための木と出発点をオフにバックアップするたびに要求されます。
一般的な形式
第一の擬似コードを直接与えられます。
inline void update(int *树状数组起点,int 树状数组尺寸,int 询问位置,int 更新值){
while(下标<=尺寸){
进行更新,
下标加上lowbit
}
}
inline void update(int *树状数组起点,int 树状数组尺寸,int 询问位置){
while(下标不为零){
统计贡献
下标减去lowbit
}
}
コール
update(树状数组+起点[i],尺寸[i],位置,值)
printf(query(树状数组+起点[i],尺寸[i],位置))
それは見ることができ、いくつかの分割の配列は、自然フェンウィックツリーのすべてを満たしているため、一般的なフェンウィックツリーは、ほとんど同じです。
例
P3960パレード
この質問は、抽象の維持する必要がある\(N \)ライン\(Q \)の間隔を、構築する必要が\を(N \)間隔ごと、我々は区間番号の行番号でソートすることができ、この時間をアレイサポートバイナリ検索長内蔵\(Q \)ツリーアレイを、次いで、上記の方法で、アレイの各列のツリーを構築し、複雑なバイナリサーチ検索が実行されてもよいです。
inline void update(LL *ar,int siz,int x,LL c){
while(x<=siz){
ar[x]+=c;
x+=x&(-x);
}
}
inline int query(LL *ar,int siz,int x){
/*binary search*/
int l=1,r,mid,sum,ret;
while(l<=siz&&ar[l]<x){
l<<=1;
ret=l;
}
r=l;
sum=ar[(l>>=1)];
while(l<r-1){
mid=(l+r)>>1;
if(mid>siz||ar[mid]+sum>=x){
r=mid;
ret=mid;
}else{
l=mid;
sum+=ar[l];
}
}
ret=r;
return ret;
}