普通的單點修改單點查詢就不講了,從區間修改和單點查詢講起。
原來的值存在a裡面,多建立個陣列c1,注意:c1[i]=a[i]-a[i-1]。
那麼求a[i]的值的時候a[i]=a[i-1]+c1[i]=a[i-2]+c1[i]+c1[i-1]=…..=c1[1]+c1[2]+…+c1[i]。
所以就用c1建立樹狀陣列,便可以很快查詢a[i]的值。不多說,見**。
#include#include#define lb(x) x&-x
#define maxn 1000000
#define in(x) scanf("%d",&x)
#define in3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
int a[maxn],c1[maxn],n,m,val,x,y,temp;
void update(int x,int val)
}int sum(int x)
return ans;
}main()
while(m--)
else
}}
自認為還是比較好看懂的,接下來是區間修改和區間查詢了。
我們用sum(1,k)表示區間1到k的和。
那麼sum(1,k)=c1(1)+(c1(2)+c1(2))+(c1(1)+c1(2)+c1(3))+…+(c1(1)+c1(2)+…+c1(k))。
然後我們把式子開啟。
sum(1,k)=k*(c1(1)+c1(2)+c1(3)+…+c1(k))-(0*c1*(1)+1*c1(2)+2*c1(3)+…+(k-1)*c1(k))。
是不是有些小激動,我們可以多建立乙個陣列c2,c2[n]用來存(n-1)*c1(n),並且把c2陣列也建立成樹狀陣列,那麼問題就迎刃而解了。
詳見**:
#include#include#define lb(x) x&-x
#define ll long long
#define maxn 1000000
#define in(x) scanf("%lld",&x)
#define in3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
using namespace std;
ll a[maxn],c1[maxn],c2[maxn],n,m,val,x,y,temp;
void update(ll *q,ll x,ll val)
}ll getsum(ll *q,ll x)
return ans;
}ll sum(ll x)
ll inquire(ll x,ll y)
int main()
for(ll i=1; i<=m; i++)
else
}}
樹狀陣列 區間修改 單點查詢
說一下差分 現在我們有乙個從小到大的數列a a 1 3 6 8 9 然後還有乙個差分陣列b b 1 2 3 2 1 對應 1,3 1,6 3,8 6,9 8,相信某些同學絕已經看出端倪了.這裡b i a i a i 1 我令a 0 0,故b 1 a 1 int now 0,temp scanf d ...
樹狀陣列(區間修改,單點查詢)
如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的值 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表示乙個操作,具體如下 操...
樹狀陣列 單點修改區間查詢
樹狀陣列,時間複雜度o mlogn 明顯優於暴力列舉以及字首和,主要用於單點修改區間查詢 當然還有區間修改單點查詢 如果一道題中只有區間查詢,那麼建議使用字首和維護 思想直接理解不好理解,借助資料 a陣列下標12 3456 78數值2 5632 714以上是我們要儲存的a陣列,就是原資料 b陣列下標...