luogu3368 模板 樹狀陣列 2

2021-08-19 05:05:30 字數 1564 閱讀 2255

題面

已知乙個數列,你需要進行下面兩種操作:

1.將某區間每乙個數數加上x

2.求出某乙個數的和

題解1單點查詢+區間修改。

-。-說了樹狀陣列模板那就用樹狀陣列。

樹狀陣列維護差分數列即可(差分字首和是逆操作,樹狀陣列原先的區間查詢就變成了單點查詢了)。

來介紹一下差分

設陣列a=,那麼差分陣列b=

也就是說b[i]=a[i]-a[i-1];(a[0]=0;),那麼a[i]=b[1]+….+b[i];(這個很好證的)。

假如區間[2,4]都加上2的話

a陣列變為a=,b陣列變為b=;

發現了沒有,b陣列只有b[2]和b[5]變了,因為區間[2,4]是同時加上2的,所以在區間內b[i]-b[i-1]是不變的.

所以對區間[x,y]進行修改,只用修改b[x]與b[y+1]:

b[x]=b[x]+k;b[y+1]=b[y+1]-k;

#include

#include

using

namespace

std;

const

int maxn = 500050;

int n, m, a[maxn];

void add(int x, int k)

int query(int x)

int main()

for(int i = 1; i <= m; i++)else

}return

0;}

題解2

區間題照例線段樹,容易卡常,用手寫輸入輸出。

#include

#include

using

namespace

std;

const

int maxn = 500050;

int readint()

while(ch>='0'&&ch<='9')

return op*x;

}void outint(int x)

if(x>9)outint(x/10);

putchar(x%10+'0');

}int a[maxn];

struct nodesgt[maxn<<2];

void build(int p, int l, int r)else

}void pushdown(int p)

}void add(int p, int l, int r, int v)

pushdown(p);

int m = (sgt[p].l+sgt[p].r)/2;

if(l <= m)add(p*2,l,r,v);

if(r > m)add(p*2+1,l,r,v);

sgt[p].val = sgt[p*2].val+sgt[p*2+1].val;

}int query(int p, int l, int r)

int main()else

}return

0;}

luogu3368 模板 樹狀陣列 2

題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的和 輸入輸出格式 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表...

luogu3368 樹狀陣列 差分

如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的和 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表示乙個操作,具體如下 操...

洛谷 3368 模板 樹狀陣列 2

題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某乙個數的值 輸入輸出格式 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表...