zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    WalkDirFiles
    http://ocpj8.javastudyguide.com/
    打印文件夹中的文件
    apple
    JDBC
    JDBC connection
    Properties-getProperty
    删除目录中指定文件
    spark 之knn算法
    hbase查询基于标准sql规范中间件Phoenix
  • 原文地址:https://www.cnblogs.com/bifanwen/p/13199898.html
Copyright © 2011-2022 走看看