原題連結:https://www.luogu.com.cn/problem/P3368
題意解讀:樹狀陣列應用-區間修改,單點求值
解題思路:
設原陣列為s[N],其差分陣列為a[N]
操作一:區間修改
要對s[x] ~ s[y]每個數增加k,相當於對a[x]加k,對a[y + 1]減k,O(n)的操作變成了O(1)的操作,
利用樹狀陣列tr[N]的add(x, k), add(y + 1, -k)來實現對於a[N]的操作即可.
操作二:單點求值
要求s[x]的值,相當於求a[1] ~ a[x]所有數的和,
利用樹狀陣列的sum(x)求和即可。
樹狀陣列初始化:
初始化時,要對原陣列的值求差分,新增到樹狀陣列。
100分程式碼:
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int n, m;
int s[N], tr[N];
int lowbit(int x)
{
return x & -x;
}
void add(int x, int val)
{
for(int i = x; i <= n; i += lowbit(i)) tr[i] += val;
}
int sum(int x)
{
int res = 0;
for(int i = x; i != 0; i -= lowbit(i)) res += tr[i];
return res;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
cin >> s[i];
add(i, s[i] - s[i - 1]); //構造差分的樹狀陣列
}
int op, x, y, k;
while(m--)
{
cin >> op;
if(op == 1)
{
cin >> x >> y >> k;
add(x, k);
add(y + 1, -k);
}
else if(op == 2)
{
cin >> x;
cout << sum(x) << endl;
}
}
return 0;
}