• P3368 【模板】树状数组 2 题解


    CSDN同步

    原题链接

    前置知识:

    树状数组的单点修改与区间询问。

    简要题意:维护数组的区间修改与单点询问。

    同样类似的,我们用 树状数组 进行操作,对每个区间修改,本质上 是对差分数组的前缀和的维护,而前缀和的维护我们需要用到 树状数组

    树状数组以常数小,空间小比线段树好用,好写(但是功能没有线段树多)。

    所以对每个区间 ([l,r]) ,更新 (l)(r+1) 的差分值即可。

    时间复杂度:(mathcal{O}(n log n) - mathcal{O}(log n)).

    实际得分:(100pts).

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e6+1;
    typedef long long ll;
    
    inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
    	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
    
    int a[N]; ll c[N];
    int n,m,x,y;
    
    inline int lowbit(int x) {
    	return x & (-x);
    }
    
    inline ll sum(int x) { //单点查询 
    	ll s=0; while(x>0) {
    		s+=c[x];
    		x-=lowbit(x);
    	} return s;
    }
    
    inline void update(int x,int k) {
    	while(x<=n) {
    		c[x]+=k;
    		x+=lowbit(x); 
    	}
    }
    
    int main(){
    	n=read(); m=read();
    	for(int i=1;i<=n;i++) {
    		a[i]=read(); update(i,a[i]-a[i-1]); //差分数组的维护
    	} while(m--) {
    		int opt=read(),x,y,k;
    		if(opt==1) {
    			x=read(),y=read(),k=read();
    			update(x,k); update(y+1,-k); } else {
    			x=read();
    			printf("%lld
    ",sum(x)); //维护差分,询问
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Go语言基础--1.1 变量的声明
    基本语法
    弹性盒子修改
    弹性盒子内容
    弹性盒子
    响应式列重置
    栅格系统
    布局容器
    额外按钮
    可消失的弹出框
  • 原文地址:https://www.cnblogs.com/bifanwen/p/13199898.html
Copyright © 2020-2023  润新知