單點修改:
不需要差分
區間修改,單點查詢: //參考
假設現在有乙個原陣列a(假設a[0] = 0),有乙個陣列d,d[i] = a[i] - a[i-1],那麼
a[i] = d[1] + d[2] + .... + d[i]
d陣列就是差分陣列
所以求a[i]就可以用樹狀陣列維護d[i]的字首和
區間修改,單點查詢:
根據d的定義,對[l,r]區間加上x,那麼a[l]和a[l-1]的差增加了x,a[r+1]與a[r]的差減少了x,所以就對差分陣列的字首和進行修改
設c是差分陣列的字首和
注意:差分 輸入的時候要以差的形式
for(int i=1;i<=n;i++)
void add(int x,intk)
int sum(int區間修改,區間查詢:x)
根據上面的差分陣列的定義可以得到:
a[1] + a[2] + a[3] + ... + a[k] = d[1] + d[1] + d[2] + d[1] + d[2] + d[3] + ... + d[1] + d[2] + d[3] + ... + d[k]
= σ(k - i + 1) * d[i] (i從1到k)
變化一下 σa[i] (i從1到k) = σ(k+1) * d[i] - i * d[i] (i從1到k)
d[i]可以用乙個字首和維護,i * d[i]也可以用乙個字首和進行維護,所以區間修改,區間查詢就變得很方便了
假設c1維護d[i]的字首和,c2維護d[i] * i的字首和
void add(int x,inty)
int sum(int樹狀陣列求 逆序對:x)
return ans1 -ans2;
}
方法1的部落格
(但有0就死迴圈了,所以前提a[i]>0)
但又侷限性,a[ i ]的最大值不能很大,否則陣列會爆
因此,引進離散化+樹狀陣列
方法2的部落格
a[i].num 3 7 2 4 6
a[i].pos 1 2 3 4 5
對結構體a按num值從小到大排序,得到:
a[i].num 2 3 4 6 7
a[i].pos 3 1 4 5 2
for(int i=1;i<=n;i++) aa[ a[i].pos ]=i; 會得到:
i: 1 2 3 4 5
aa[i]: 2 5 1 3 4
這樣的 aa[i]中各位數字 2 5 1 3 4的相對大小和原陣列a[i].num 3 7 2 4 5 是一樣的。這樣做減少了不必要的空間。 a[i] 可為0
去重離散化的兩種方法:
struct去重離散化1node
aa[n];
bool
cmp(node x,node y)
intmain()
a[aa[i].p] =cnt;}}
for(i=1;i<=n;++i) cin>>a[i], b[i]=a[i];去重離散化2void
discretize()
vectorv;去重離散化3sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()) , v.end());
...=lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
第二種去重不太徹底,5 8 8 10,離散化之後是 1 2 2 4
hdu二維樹狀陣列題:新年彩燈2
思路:二維轉為多個一維的就行了
1 #include2 #include3 #include 4 #include5 #include6 #include7 #include**8 #include9 #include
10 #include11 #include12 #include13 #include14
using
namespace
std;
15#define ll long long
16#define mem(a,x) memset(a,x,sizeof(a))
17#define se second
18#define fi first
19const ll mod=1e9+7;20
const
int inf= 0x3f3f3f3f;21
const
int n=1e6+5;22
23int c[1005][1005
];24
intn,m;
2526
int lowbit(int
i)27
3031
void add(int x,int y,int
k)32
3536
int sum(int x,int
y)37
4243
intmain()
4462}63
else
6471
}72 }
樹狀陣列總結
樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...
樹狀陣列總結
樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...
樹狀陣列總結
今天學習了一下樹狀陣列,做乙個簡單總結。樹狀陣列可分為兩種操作,1 修改單個點,統計區間和 一般為 向上修改 update1 向下統計 sum1 2 修改區間,統計單個點 一般為向下修改 update2 向上統計 sum2 主要模板如下 int c n int lowbit int x 用於確定區間...