BIT + sparse table

BIT

binary indexed tree (fenwick tree)

  • 前綴和 \(O(\log n)\)
  • 單點修改 \(O(\log n)\)

跟線段樹相比:實作點單不少,常數小很多

把他當黑科技

算區間和:前綴和相減就變區間和了

int bit[200010], n;

void upd(int pos, int x){
  while(pos<=n){
    bit[pos]+=x;
    pos+=pos&-pos;
  }
}

int qry(int pos){
  int res=0;
  while(pos>0){
    res+=bit[pos];
    pos-=pos&-pos;
  }
  return res;
}

一定是1-based

Sparse Table

稀疏表

處理區間查詢,如最大最小,gcd等(不能區間和)

 

\(O(n\log n)\) 預處理

\(O(1)\)查詢

 

不能修改

建立一個二維陣列,\(sp[N][\lfloor log_2N\rfloor]\),N為陣列長度

\(sp[i][j]\) = \(i\)到\(i+2^j\)的最小值

\(sp[i][j]=min(sp[i][j-1], sp[i+2^{j-1}][j-1])\)

建表

複雜度: \(O(n\log n)\)

若詢問l~r

 

答案為\(min(sp[l][j], sp[r-2^j+1][j])\)

 

其中\(j=\lfloor log_2LEN\rfloor\)

查詢

複雜度: \(O(1)\)

#include <bits/stdc++.h>
using namespace std;

int num[500001], sp[500001][20], log_2[500001];

int query(int l, int r){
    int k=log_2[r-l+1];
    return min(sp[l][k], sp[r-(1<<k)+1][k]);
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n
    cin >> n;

    // generates logarithm table of 2 (only needs n value)
    log_2[1]=0;
    for(int i=2;i<=n;++i) log_2[i]=log_2[i/2]+1;

    //build
    for(int i=0;i<n;++i){ //init
        cin >> num[i];
        sp[i][0]=num[i];
    }
    for(int j=1;j<=log_2[n];++j)
        for(int i=0;i+(1<<j)-1<n;++i)
            sp[i][j]=max(sp[i][j-1], sp[i+(1<<(j-1))][j-1]);
}

BIT + sparse table

By alan lai

BIT + sparse table

  • 127