首先最基础的区间查询,单点修改:
void add(int x, int y) {
for (; x <= n; x += x & -x) {
dp[x] += y;
}
}
int solve(int x) {
int X = x,ans=0;
for (; x; x -= x & -x) {
ans += dp[x];
}
return ans;
}
然后利用差分思想实现区间操作,单点查询:
int last=0;
for(int i=1;i<=n;i++){
add(i,a[i]-last);
last=num[i];
}//初始化
...
int l,r,k;
add(l,k),add(r+1,-k);//向l-r区间插入k
...
//查询不变
最后,区间操作,区间修改(例如守墓人):
我们搞两个数组去搞一些骚的:
void add(long long x, long long y) {
int X = x-1;
for (; x <= n; x += x & -x)dp[x] += y,dp2[x]+=y*X;
}
long long solve(long long x) {
long long ans = 0;
long long X = x;
for (; x; x -= x & -x) {
ans += dp[x]*X-dp2[x];
}
return ans;
}
//其余与区间修改单点查询相同
(写这篇笔记主要是因为我好像总是把这三个操作搞混...)