• 指针版的线段树


    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1000005;
    struct node
    {
        int sum,l,r,num;
        node *left,*right;
    }tree[N];
    int x,t,outit[N];
    long long ans;
    vector<int> aqueue[N];
    struct point 
    {
        int val,loc;
    }data[N];
    void buildtree(node *root,int l,int r)
    {
        root->l=l;
        root->r=r;
        root->left=&tree[++t];
        root->right=&tree[++t];
        root->sum=0;
        if(l==r)
        {
            root->num=l;
            return ;
        }
        int mid=l+r; mid/=2;
        buildtree(root->left,l,mid);
        buildtree(root->right,mid+1,r);
    }
    void update(node *root,int i)
    {
        root->sum++;
        if(root->l==i&&root->r==i)
        {
            return ;
        }
        int mid=root->l+root->r; mid/=2;
        if(i<=mid)
        {
            update(root->left,i);
            return ;
        }
        else
        {
            update(root->right,i);
            return ;
        }
    }
    int search_down(node *root,int x)
    {
        int mid = root->l+root->r; mid/=2;
        if(x==root->l&&x==root->r)
        return 0;
        if(x<=mid)
        {
            return search_down(root->left,x)+root->right->sum;
        }
        if(x>mid)
        {
            search_down(root->right,x);
        }
    }
    int  query(int x)
    {
        int y= search_down(tree,x);
        return y;
    }
    bool cmp(point a,point b)
    {
        if(a.val<b.val)
        return true;
        return false;
    }
    int main()
    {
        int n;
        cin>>n;
        buildtree(tree,1,n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&data[i].val);
            data[i].loc=i;
        }
        sort(data+1,data+1+n,cmp);
        for(int j=1,i=1;i<=n;i++,j++)
        {
            if(data[i].val==data[i-1].val)
            j--;
            aqueue[j].push_back(data[i].loc);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=aqueue[i].size()-1;j>=0;j--)
            {
                outit[aqueue[i][j]]=i;
            }
        }
    //  for(int i=1;i<=n;i++)
    //  printf("%d ",outit[i]);
        for(int i=1;i<=n;i++)
        {
            x=outit[i];
            update(tree,x);
            ans+=query(x);
        }
        cout<<ans;
        return 0;
    }
    

    其实用指针写的线段树会非常的简单,其实大家可以学习一下,非常的好懂,只要能够理解基础线段树的代码意思就可以了。(pushdown要认真理解)!!!

  • 相关阅读:
    【DOS命令】type
    【shell】$符号操作
    【C++百科】STL(Standard Template Library) 标准模板库简介
    【配置与安装】SSH 密钥类型的的选择(RSA, DSA or Other)
    【百科通识】CPU x86/x86-64/x64/i386
    【配置与安装】SSH远程开发
    【百科通识】.bat文件
    【vi】模式切换
    【vim】撤销与回退
    【C++】智能指针
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330740.html
Copyright © 2020-2023  润新知