1 条题解
-
0
分析:
本题给定一个整数序列,需要支持对序列中某个位置的值进行更新操作,并在每次更新后计算一个特定的结果。算法思想是利用线段树来维护序列的区间信息,包括区间和、区间最大子段和、区间最小子段和等。通过构建线段树,可以高效地处理单点更新操作,并在更新后快速计算出所需的结果。
解题原理
1.线段树的构建:将序列划分为不同的区间,每个区间对应线段树的一个节点。通过递归的方式构建线段树,对于每个节点,其左右子节点分别对应该区间的左右子区间。在构建过程中,使用 pushup 函数将子节点的信息合并到父节点,从而得到整个区间的信息。
2.单点更新:当需要更新序列中某个位置的值时,从线段树的根节点开始,递归地找到对应的叶子节点,更新该节点的值,然后通过 pushup 函数向上更新其父节点的信息,保证线段树中存储的信息始终是最新的。
3.结果计算:根据线段树中存储的区间和、区间最大子段和、区间最小子段和的信息,计算出最终结果。如果区间和等于区间最大子段和,则结果为区间和减去区间最小子段和;否则,结果为区间最大子段和与区间和减去区间最小子段和中的较大值。
实现步骤
1.输入处理:读取序列的长度 n 和序列中的每个元素,存储在数组 a 中。
2.线段树构建:调用 build 函数,从根节点(编号为 1)开始,递归地构建线段树,将序列的信息存储在线段树中。
3.更新操作处理:读取更新操作的次数 m,对于每次更新操作,读取要更新的位置 u 和新的值 v,调用 updata 函数更新线段树中对应位置的值。
4.结果计算与输出:在每次更新操作后,根据线段树中存储的信息计算结果,并输出结果。
通过以上步骤,利用线段树的高效性,实现了对序列的单点更新和结果计算。
C++代码:
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f3f; const int N = 100005; int a[N],tree[N],lazy[N]; int sum[N<<2],maxkey[N<<2],minkey[N<<2]; int lmax[N<<2],rmax[N<<2]; int lmin[N<<2],rmin[N<<2]; void pushup(int k) { int l = k << 1; int r = k << 1 | 1; sum[k] = sum[l] + sum[r]; maxkey[k] = max(max(maxkey[l],maxkey[r]),rmax[l] + lmax[r]); minkey[k] = min(min(minkey[l],minkey[r]),rmin[l] + lmin[r]); lmax[k] = max(lmax[l],sum[l]+lmax[r]); rmax[k] = max(rmax[r],sum[r]+rmax[l]); lmin[k] = min(lmin[l],sum[l]+lmin[r]); rmin[k] = min(rmin[r],sum[r]+rmin[l]); } void build(int l,int r,int k) { if(l == r) { maxkey[k] = minkey[k] = lmax[k] = rmax[k] = lmin[k] = rmin[k] = sum[k] = a[l]; } else { int mid = l + ((r - l) >> 1); build(l,mid,k<<1); build(mid+1,r,k<<1|1); pushup(k); } } void updata(int p,int v,int l,int r,int k) { if(l == r) { sum[k] = maxkey[k] = minkey[k] = v; lmax[k] = rmax[k] = lmin[k] = rmin[k] = v; } else { int mid = l + ((r - l) >> 1); if(p <= mid) { updata(p,v,l,mid,k<<1); } else { updata(p,v,mid+1,r,k<<1|1); } pushup(k); } } int main() { int n,m; int u,v; scanf("%d",&n); for(int i = 1;i <= n; ++i) { scanf("%d",&a[i]); } build(1,n,1); scanf("%d",&m); while(m--) { scanf("%d%d",&u,&v); updata(u,v,1,n,1); int ans; if(sum[1] == maxkey[1]) ans = sum[1] - minkey[1]; else ans = max(maxkey[1],sum[1] - minkey[1]); printf("%d\n",ans); } return 0; }
- 1
信息
- ID
- 1750
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者