单点更新:
#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
const int MAXNODE = 1 << 19;
const int MAX = 2e5 + 10;
typedef struct Node
{
int left;
int right;
int value;
};
Node node[MAXNODE];
int father[MAX];//记录位置
void BuildTree(int i,int left,int right)//构造线段数和初始化
{
node[i].left = left;
node[i].right = right;
node[i].value = 0;
if(left == right)
{
father[left] = i;
return ;
}
else
{
int temp = (left + right) / 2.0;
BuildTree(i << 1,left,temp);
BuildTree((i << 1) + 1,temp + 1,right);
}
}
void Update(int ri)//更新
{
if(ri == 1)
return ;
int fi = ri / 2;
int a = node[fi << 1].value;
int b = node[(fi << 1) + 1].value;
node[fi].value = a + b;
Update(fi);
}
int M;
void query(int i,int l,int r)//询问查找
{
if(node[i].left == l && node[i].right == r)
{
M += node[i].value;
return ;
}
i = i << 1;
if(l <= node[i].right)
{
if(r <= node[i].right)
{
query(i,l,r);
}
else
{
query(i,l,node[i].right);
}
}
i += 1;
if(r >= node[i].left)
{
if(l >= node[i].left)
{
query(i,l,r);
}
else
{
query(i,node[i].left,r);
}
}
}
int main()
{
ios::sync_with_stdio(false);//不用会T,或者使用scanf printf
int T;
cin >> T;
int t = 1;
while(T--)
{
cout << "Case " << t++ << ':'<< endl;
int n;
cin >> n;
BuildTree(1,1,n);
for(int i = 1;i <= n; ++i)
{
int v;
cin >> v;
node[father[i]].value = v;//将值存入最底层
Update(father[i]);
}
string s;
while(cin >> s && s[0] != 'E')
{
int a,b;
cin >> a >> b;
if(s[0] == 'Q')
{
M = 0;
query(1,a,b);
cout << M << endl;
}
if(s[0] == 'A')
{
node[father[a]].value += b;
Update(father[a]);
}
if(s[0] == 'S')
{
node[father[a]].value -= b;
Update(father[a]);
}
}
}
}
单点更新(回溯):
#include<cstdio>
#include<iostream>
#include<string>
const int MAXN = 2e5 + 10;
using namespace std;
#define lson l,m,i << 1
#define rson m + 1,r,i << 1 | 1
typedef struct Node
{
int l,r;
int mid()
{
return (l + r) / 2.0;
}
int value;
};
Node node[MAXN << 2];
void push_up(int i)
{
node[i].value = max(node[i << 1].value,node[i << 1 | 1].value);
}
void Build(int l,int r,int i)
{
node[i].l = l;
node[i].r = r;
node[i].value = 0;
if(l == r)
{
cin >> node[i].value;
return ;
}
int m = node[i].mid();
Build(lson);
Build(rson);
push_up(i);
}
int M;
void query(int l,int r,int i)
{
if(node[i].l == l && node[i].r == r)
{
M = max(node[i].value,M);
return ;
}
int m = node[i].mid();
if(r <= m)
query(l,r,i << 1);
else
if(l > m)
query(l,r,i << 1 | 1);
else
{
query(lson);
query(rson);
}
}
void update(int l,int r,int i,int v,int num)
{
if(l == r && l == num)
{
node[i].value = v;
return ;
}
int m = node[i].mid();
if(m >= num)
update(l,m,i << 1,v,num);
else
update(m + 1,r,i << 1 | 1,v,num);
push_up(i);
}
int main()
{
ios::sync_with_stdio(false);
int n,m,a,b;
string s;
while(cin >> n >> m)
{
Build(1,n,1);
while(m--)
{
cin >> s >> a >>b;
if(s[0] == 'Q')
{
M = 0;
query(a,b,1);
cout << M << endl;
}
else
{
update(1,n,1,b,a);
}
}
}
}
线段数区间求和(延迟标记)
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
typedef struct Node
{
int l;
int r;
int mid()
{
return (l + r) / 2.0;
}
};
LL ans;
Node node[N << 2];//为什么乘4
LL add[N << 2];// 延迟标记数组
LL sum[N << 2];//每个节点的sum
void PushUp(int i);
#define lson i << 1,l,m
#define rson i << 1 | 1,m + 1,r
void build(int i,int l,int r)//建树并完成初始化
{
node[i].l = l;
node[i].r = r;
sum[i] = 0;
add[i] = 0;
if(l == r)
{
cin >> sum[i];//在内部输入,为叶子节点
return ;//一定要写return!!!
}
int m = node[i].mid();
build(lson);//只想下更新sum
build(rson);
PushUp(i);//递归回去完成区间的更新.
}
void PushUp(int i) // 建树递归返回时更新。
{
sum[i] = sum[i << 1] + sum[i << 1 | 1];
}
void PushDown(int i,int L) // L为区间长度 (延迟标记)
{
if(add[i])
{
add[i << 1] += add[i];
add[i << 1 | 1] += add[i];
sum[i << 1] += add[i] * (L - (L >> 1)); // 易错
sum[i << 1 | 1] += add[i] * (L >> 1);
add[i] = 0;
}
}
void update(int v,int l,int r,int i)//更新操作,区间【l,r】加值v
{
if(node[i].l == l && node[i].r == r)//当找到目标区间时,
{
sum[i] += (LL)v * (r - l + 1);//更新当前节点的值,
add[i] += v;//延迟标记+V
return ;
}
PushDown(i,node[i].r - node[i].l + 1);// 因为没有匹配到合适的区间,向下寻找,检查这个区间是否有标记.
int m = node[i].mid();//如果有标记,说明应该先把之前的标记量给计算出,再进行寻找.
if(r <= m)
{
update(v,l,r,i << 1);
}
else
{
if(l > m)
update(v,l,r,i << 1 | 1);
else
{
update(v,l,m,i << 1);
update(v,m + 1,r,i << 1 | 1);
}
}
PushUp(i);//递归返回
}
void query(int l,int r,int i) //查询
{
if(node[i].l == l && node[i].r == r)
{
ans += sum[i];
return ;
}
PushDown(i,node[i].r - node[i].l + 1);
int m = node[i].mid();
if(r <= m)
query(l,r,i << 1 );
else
{
if(l > m)
query(l,r,i << 1 | 1);
else
{
query(l,m,i << 1);
query(m + 1,r,i << 1 | 1);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
while(cin >> n >> m)
{
build(1,1,n);
string s;
while(m--)
{
int a,b,c;
cin >> s;
if(s[0] == 'Q')
{
ans = 0;
cin >> a >> b;
query(a,b,1);
cout << ans << endl;
}
else
{
cin >> a >> b >> c;
update(c,a,b,1);
}
}
}
}