zoukankan      html  css  js  c++  java
  • 蒟蒻の树状数组学习总结

    定义

    树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。

    这种数据结构(算法)并没有C++和Java的库支持,需要自己手动实现。在Competitive Programming的竞赛中被广泛的使用。树状数组和线段树很像,但能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。

    解决问题

    可以解决大部分基于区间上的更新以及求和问题。

    模板

    #include<iostream>
    using namespace std;
    int n,m,i,num[100001],t[200001],l,r;//num:原数组;t:树状数组 
    int lowbit(int x){
        return x&(-x);
    }
    void change(int x,int p){//将第x个数加p 
        while(x<=n){
            t[x]+=p;
            x+=lowbit(x);
        }
        return;
    }
    int sum(int k){//前k个数的和 
        int ans=0;
        while(k>0){
            ans+=t[k];
            k-=lowbit(k);
        }
        return ans;
    }
    int ask(int l,int r){//求l-r区间和
        return sum(r)-sum(l-1); 
    }
    int main(){
        cin>>n>>m;
        for(i=1;i<=n;i++){
            cin>>num[i];
            change(i,num[i]);
        }
        for(i=1;i<=m;i++){
            cin>>l>>r;
            cout<<ask(l,r)<<endl;
        }
        return 0;
    }
    

    例题

    P3374 【模板】树状数组 1

    思路

    一道涉及区间修改简单 模板题,结果本蒟蒻居然还错了两次,一次错在数组开小,第二次发现超时了,结果发现num数组根本不需要!直接将值作为一个变量输入并存入树状数组就行了qwq

    失误总结

    不必要的变量千万别瞎加!不然会拖慢读入的速度

    C o d e Code Code

    #include<iostream>
    using namespace std;
    int n,m,i,a,t[500010],l,r;//num:原数组;t:树状数组 
    int ord,x,k;
    int lowbit(int x){
        return x&(-x);
    }
    void change(int x,int p){//将第x个数加p 
        while(x<=n){
            t[x]+=p;
            x+=lowbit(x);
        }
        return;
    }
    int sum(int k){//前k个数的和 
        int ans=0;
        while(k>0){
            ans+=t[k];
            k-=lowbit(k);
        }
        return ans;
    }
    int ask(int l,int r){//求l-r区间和
        return sum(r)-sum(l-1); 
    }
    int main(){
        cin>>n>>m;
        for(i=1;i<=n;i++){
            cin>>a;
            change(i,a);
        } 
        for(i=1;i<=m;i++){
    		cin>>ord;
    		if(ord==1){
    			cin>>x>>k;
    			change(x,k);
    		}else{
    			cin>>l>>r;
    			cout<<ask(l,r)<<endl;
    		}
        }
        return 0;
    }
    
    她透过我的血,看到了另一抹殷红
  • 相关阅读:
    在c#中使用全局快捷键
    把其他C/C++编译器集成到VC2005中
    零基础学习Oracle 10G视频教程
    异常处理 Exception
    序列化与反序列化 BinaryFormatter二进制(.dat)、SoapFormatter(.soap)、XmlSerializer(.xml)
    MVC 数据验证
    MVC 路由规则
    分部类,分部方法 修饰符partial
    HttpRuntime类
    MVC 模型绑定
  • 原文地址:https://www.cnblogs.com/zhangbeini/p/13771252.html
Copyright © 2011-2022 走看看