zoukankan      html  css  js  c++  java
  • 树状数组

    代码来自转载

    优秀博客
    http://www.cnblogs.com/AC-King/p/7789013.html
    https://www.cnblogs.com/acgoto/p/8588304.html

    https://www.cnblogs.com/acgoto/p/8583952.html

    int lowbit(int i)
    {
        return i & -i;
    }
    
    void update(int i,int val)
    {
        while(i<=n){
            C[i]+=val;
            i+=lowbit(i);
        }
    }
    
    int sum(int i)
    {
        int ret=0;
        while(i>0){
            ret+=C[i];
            i-=lowbit(i);
        }
        return ret;
    }
    

    HDU 1745
    转载

    #include<bits/stdc++.h>
    using namespace std;//思路:将编号划分区间,进行建树,然后有数据的更新,删除,查询
    const int maxn = 200005;
    int a,b,q[maxn],t[maxn<<2];//a,b是操作数,q是存放学生成绩,t是建树的节点数,t数组的长度一般是原数据的长度的4倍,来记录区间的最大值
    void build(int l,int r,int x)//建树
    {
        int mid=(l+r)>>1;//取中间值
        if(l==r){//区间只有一个正数,即叶子节点的值就是q数组中保存的值
            t[x]=q[mid];
            return;
        }
        build(l,mid,x<<1);//递归建立左子树2*x
        build(mid+1,r,x<<1|1);//递归建立右子树2*x+1
        t[x]=max(t[x<<1],t[x<<1|1]);//建立完左子树和右子树之后返回到父节点,此时父节点的值等于左右子树的最大值
    }
    int query(int l,int r,int x)//查询
    {//[a,b]、[l,r]
        if(a<=l && b>=r)return t[x];//如果该节点表示的区间恰好是要查询的区间,直接返回结果,即[l,r]是[a,b]的一个子集,直接返回最大值
        else{
            int mid=(l+r)>>1;
            if(b<=mid)return query(l,mid,x<<1);//判断(编号)区间在哪棵子树上[a,b]在[l,r]的左子树[l,mid]上
            else if(a>mid)return query(mid+1,r,x<<1|1);//[a,b]在[l,r]的右子树[mid+1,r]上
            else return max(query(l,mid,x<<1),query(mid+1,r,x<<1|1));//表示[a,b],有一部分在[l,mid]上,有一部分在[mid+1,r]上,直接返回左右区间的最大值
        }
    }
    void modify(int l,int r,int x)//更新节点,更改值,x为编号
    {//[l,r],此时的a为学生编号ID、b为成绩值
        if(l==r){//找到叶子节点
            t[x]=b;//把a的成绩改成b的成绩
            return;
        }
        int mid=(l+r)>>1;//判断更新节点在哪棵树上
        if(a<=mid){modify(l,mid,x<<1),t[x]=max(t[x<<1],t[x<<1|1]);}//如果编号a在[l,mid]上,递归修改,直到叶子节点,返回到父节点时,父节点保存左右子树的最大值
        else{modify(mid+1,r,x<<1|1),t[x]=max(t[x<<1],t[x<<1|1]);}//同时更新节点的最大值
    }//回溯的时候将所有的父节点给更新了
    int main()
    {
        int m,n;char ch;
        while(~scanf("%d %d",&n,&m)){
            for(int i=1;i<=n;++i)scanf("%d",&q[i]);
            build(1,n,1);//建树
            while(m--){
                getchar();//吃掉回车符的影响
                scanf("%c %d %d",&ch,&a,&b);
                if(ch=='Q')printf("%d
    ",query(1,n,1));//返回最大值
                else modify(1,n,1);//进行修饰
            }
        }
        return 0;
    }
    
    透过泪水看到希望
  • 相关阅读:
    C#字符串(截取)
    字符串的截取(从指定位置)
    UVALive 7146 Defeat the Enemy(贪心+STL)(2014 Asia Shanghai Regional Contest)
    UVALive 7148 LRIP(树的分治+STL)(2014 Asia Shanghai Regional Contest)
    Google Code Jam Round 1A 2015 解题报告
    编程之美2015资格赛 解题报告
    ZOJ 3781 Paint the Grid Reloaded(BFS)
    【转】赞一下huicpc035
    【转】lonekight@xmu·ACM/ICPC 回忆录
    【转】[退役]纪念我的ACM——headacher@XDU
  • 原文地址:https://www.cnblogs.com/ronnielee/p/9571119.html
Copyright © 2011-2022 走看看