1、樹狀陣列求逆序對
#include
#include
#include
using
namespace
std;
const
int maxn=100010;
int n,a[maxn],b[maxn],c[maxn],s[maxn];
int lowbit(int x)
void add(int x)
int getsum(int x)
int main()
int ans=0;
for(int i=n;i>=1;i--)
cout
0;}
2、樹狀陣列區間修改
這裡由於涉及到區間修改,所以我們要引入差分的思想。
差分陣列c:我們設sigma(c,i)表示c陣列的前i項和,呼叫一次的複雜度是log2(i)
設原陣列是a[n],差分陣列c[n],c[i]=a[i]-a[i-1],那麼明顯地a[i]=sigma(c,i),如果想要修改a[i]到a[j],只需令c[i]+=v,c[j+1]-=v
明白了上面的原理以後,就可以直接看**了
/*區間修改+單點查詢*/
#include
#include
using
namespace
std;
const
int maxn=500010;
int n,m,a[maxn],c[maxn];
int lowbit(int x)
void add(int x,int y)
int getsum(int x)
int main()
for(int i=1;i<=m;i++)
else
}return
0;}
/*單點修改+區間查詢*/
#include
#include
using
namespace
std;
const
int maxn=500010;
int n,m,c[maxn];
int lowbit(int x)
void add(int x,int y)
int getsum(int x)
int main()
for(int i=1;i<=m;i++)
else
}return
0;}
注意:
樹狀陣列c始終是字首和陣列,即:getsum(i)始終得到的是點i的字首和。
區間修改是將樹狀陣列變成了差分陣列,所以getsum(i)得到的是差分字首和,由上面的推導,i的差分字首和,就是點i的值,所以getsum(i)是單點查詢,即:getsum(i)==a[i]
單點修改不需要差分,所以樹狀陣列維護的就是x的字首和,即getsum(x)==a[1]+a[2]+……+a[x],此時getsum()函式變成了區間查詢函式
舉個例子:x~y的區間和==getsum(y)-getsum(x-1)
拓展:
(兩個差分陣列還原了字首和陣列orz~~)
#include
#include
using
namespace
std;
const
int maxn=200010;
int n,m,s[maxn],t[maxn],r[maxn];
int lowbit(int x)
void add1(int x,int y)
void add2(int x,int y)
int find1(int x)
int find2(int x)
int getsum(int x)
int main()
scanf("%d",&m);
for(int i=1;i<=m;i++)
else
}return
0;}
關於mysql 一系列操作
這是在linux 的mysql的資料庫操作,備份資料庫 mysqldump u root p cxn usr local backupcxn.sql 引數說明 cxn 代表著我要備份的資料庫名稱,usr local backupcxn.sql代表著備份到usr local下,輩分的名稱叫做backu...
模擬動態陣列及其一系列操作
線性表是一種資料結構。在邏輯上,具有除了第乙個結點,其他結點有唯一前驅,除了最後乙個結點,其他結點有唯一後驅的特點。順序表和鏈式表是線性表的兩種實現方式,它們只在儲存方式上有區別,在邏輯上是一致的。區別在於順序表示使用連續的一段空間來儲存,我們常用的陣列就是線性表的一種順序表示。陣列是靜態分配記憶體...
SQL JOIN的一系列操作 嘎 嘎 嘎
誰訂購了產品,並且他們訂購了什麼產品?除了我們在上面的例子中使用的 inner join 內連線 我們還可以使用其他幾種連線。下面列出了您可以使用的 join 型別,以及它們之間的差異。right join 關鍵字會右表 table name2 那裡返回所有的行,即使在左表 table name1 ...