中文題目 7-10 公路村村通
阿新 • • 發佈:2022-04-02
使用場景
多次修改某個數(單點),求區間和:「樹狀陣列」
定義
模板
// 上來先把三個方法寫出來 { int[] tree; //求最低位的1 的二進位制表示 int lowbit(int x) { return x & -x; } // 查詢字首和的方法 int query(int x) { int ans = 0; for (int i = x; i > 0; i -= lowbit(i)) ans += tree[i]; return ans; } // 在樹狀陣列 x 位置中增加值 u void add(int x, int u) { for (int i = x; i <= n; i += lowbit(i)) tree[i] += u; } } // 初始化「樹狀陣列」,要預設陣列是從 1 開始 { for (int i = 0; i < n; i++) add(i + 1, nums[i]); } // 使用「樹狀陣列」: { void update(int i, int val) { // 原有的值是 nums[i],要使得修改為 val,需要增加 val - nums[i] add(i + 1, val - nums[i]); nums[i] = val; } int sumRange(int l, int r) { return query(r + 1) - query(l); } }
例題
class NumArray { int n; int[] tree; int[] nums; public NumArray(int[] nums) { n=nums.length; this.nums=nums; tree=new int[n+1]; for(int i=0;i<n;i++){ add(i+1,nums[i]); } } public int lowbit(int x){ return x&(-x); } public void update(int index, int val) { add(index+1,val-nums[index]); nums[index]=val; } public int sumRange(int left, int right) { return query(right+1)-query(left); } public void add(int index,int val){ for(int i=index;i<=n;i+=lowbit(i)){ tree[i]+=val; } } //返回前index個元素的值 public int query(int index){ int ans=0; for(int i=index;i>0;i-=lowbit(i)){ ans+=tree[i]; } return ans; } }