• bryce1010专题训练——树状数组


    Bryce1010模板
    1、一维树状数组
    https://vjudge.net/contest/239647#problem/A【HDU1556】

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int MAXN=1e5+10;
    int n,c[MAXN<<1];
    
    
    
    //表示二进制x的最末尾的一个1
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    
    //区间求和
    int getSum(int x)
    {
        int ans=0;
        while(x<=n)
        {
            ans+=c[x];
            x+=lowbit(x);
        }
        return ans;
    }
    
    //更新节点
    void update(int pos,int val)
    {
        while(pos>0)
        {
            c[pos]+=val;
            pos-=lowbit(pos);
        }
    }
    
    
    int main()
    {
        int a,b;
        while(cin>>n)
        {
            memset(c,0,sizeof(c));
            for(int i=0;i<n;i++)
            {
                cin>>a>>b;
                update(b,1);
                update(a-1,-1);
            }
            for(int i=1;i<n;i++)
                cout<<getSum(i)<<" ";
            cout<<getSum(n)<<endl;
        }
    }
    
    
    

    2、二维树状数组
    https://vjudge.net/contest/239647#problem/B【POJ 2155】

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    using namespace std;
    #define ll long long
    
    const int MAXN=1e3+123;
    int c[MAXN][MAXN];
    int n,q;
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void update(int posi,int posj,int val)
    {
        int tmpj;
        while(posi<=n)
        {
            tmpj=posj;
            while(tmpj<=n)
            {
                c[posi][tmpj]+=val;
                tmpj+=lowbit(tmpj);
            }
            posi+=lowbit(posi);
        }
    }
    
    int getSum(int posi,int posj)
    {
        int ans=0;
        int tmpj=posj;
        while(posi>0)
        {
            tmpj=posj;
            while(tmpj>0)
            {
                ans+=c[posi][tmpj];
                tmpj-=lowbit(tmpj);
            }
            posi-=lowbit(posi);
        }
        return ans;
    }
    
    
    
    
    
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
    
            char ch;
            int x1,y1,x2,y2;
            int x,y;
            scanf("%d%d",&n,&q);
            memset(c,0,sizeof(c));
            while(q--)
            {
                getchar();
                scanf("%c",&ch);
                if(ch=='C')
                {
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    update(x1,y1,1);
                    update(x2+1,y1,1);
                    update(x1,y2+1,1);
                    update(x2+1,y2+1,1);
                }
                else
                {
                    scanf("%d%d",&x,&y);
                    //查询前k的和对2取模即可
                    printf("%d
    ",getSum(x,y)%2);
                }
    
            }
            if(t)printf("
    ");
        }
    
    
        return 0;
    }
    

    3、树状数组求逆序数
    https://blog.csdn.net/Fire_to_cheat_/article/details/81129609

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    
    const int MAXN=5e5+10;
    
    
    ll sum[MAXN],n;
    struct Node
    {
        int id,digit;
        Node(){}
        Node(int i,int d):id(i),digit(d){}
    }node[MAXN];
    
    
    bool cmp(Node a,Node b)
    {
        return a.digit<b.digit;
    }
    
    ll lowbit(ll x)
    {
        return x&(-x);
    }
    
    void update(ll pos,ll val)
    {
        while(pos<=n)
        {
            sum[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    
    
    
    ll getSum(ll x)
    {
        ll ans=0;
        while(x>0)
        {
            ans+=sum[x];
            x-=lowbit(x);
        }
        return ans;
    }
    
    
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            if(n==0)break;
            int x;
            for(int i=1;i<=n;i++)
            {
                cin>>x;
                node[i]=Node(i,x);
            }
            sort(node+1,node+n+1,cmp);
            memset(sum,0,sizeof(sum));
            ll cnt=0;
            for(int i=1;i<=n;i++)
            {
                update(node[i].id,1);
                cnt+=(i-getSum(node[i].id));
            }
            cout<<cnt<<endl;
    
    
        }
        return 0;
    
    }
    
    
    
    
  • 相关阅读:
    IE浏览器中js使用中文标识符的bug
    Javascript变量作用域
    利用JS的动态语言特性对数组排序
    Javascript动态方法调用与参数修改的问题
    数组的平衡点
    Javascript中各种trim的实现
    js對象的比較
    返回两个数组中非相同的元素
    Javascript中匿名函数的多种调用方式
    SQL Server PreLogin Handshake Acknowledgement Error [duplicate]
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386859.html
Copyright © 2020-2023  润新知