1 条题解

  • 0
    @ 2025-5-4 14:31:41

    分析:

    本题给定一个整数序列,需要支持对序列中某个位置的值进行更新操作,并在每次更新后计算一个特定的结果。算法思想是利用线段树来维护序列的区间信息,包括区间和、区间最大子段和、区间最小子段和等。通过构建线段树,可以高效地处理单点更新操作,并在更新后快速计算出所需的结果。

    解题原理

    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
    上传者