Try   HackMD

樹狀數組

  • 支援:單點加值,前綴和(時間複雜度
    O(logn)
  • 空間複雜度:
    O(n)
const int MAXN; int BIT[MAXN+5]; //單點加值 void add(int k, int val){ while(k <= MAXN){ BIT[k] += val; k += (k&-k); } } //前綴和 int sum(int k){ int ret = 0; while(k){ ret += BIT[k]; k -= (k&-k); } return ret; }

離散化

  • 當只在乎序列中的大小關係的時候,可以使用離散化,縮小數值範圍
  • 其實就是排序+編碼

講講 ZJ d799

  • ZJ d799
    原本數列:
    a1,a2,a3,...,an

    =>
    a10,a2a1,a3a2,a4a3,...

    差分數列:
    d1,d2,d3,d4...
  • 區間修改,單點求值:
    • 對差分數列建 BIT
    • 修改:
      [a3,a7]
      都加上
      k
      • d3=a3a2+=k
      • d8=a8a7=k
    • 求值:
      ai=1jdj
  • 區間修改,區間和:
    • 區間和:
      [a3,a7]
      的區間和
      • 37ai=371jdj
      • =d15+d25+d35+d44+d53+d62+d71
      • =(d1+d2+d3+d4+d5+d6+d7)5(d41+d52+d63+d74)
      • a3=(d1+d2+d3)
      • a4=(d1+d2+d3+d4)
      • a5=(d1+d2+d3+d4+d5)
      • a6=(d1+d2+d3+d4+d5+d6)
      • a7=(d1+d2+d3+d4+d5+d6+d7)
    • 再建一個BIT:
      • d11,d22,d33,...
    • 區間和:
      • =(d1+d2+d3)5+(d4+d5+d6+d7)8(d44+d55+d66+d77)