Node:线段树的单点更新

来源:互联网 发布:淘宝刷关注软件 编辑:程序博客网 时间:2024/06/05 20:37
#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;const int maxn=32010;//类似一棵二叉树,加上数据和维护的区间信息struct Node{    int l,r;    int data;};//利用数组来存储二叉树Node tree[maxn*4];int ans[maxn];int n;//注意这里的pos是在树上的位置(tree的索引),而相应的l和r值得是info里面的下标//pos == 1//      1//    2   3//   4 5 6 7//   ... ...void buildTree(int pos,int l,int r){    tree[pos].l=l;    tree[pos].r=r;    //初始化数据为0    tree[pos].data=0;    //达到底部返回    if(l==r)        return;    //类似归并排序,继续递归    int mid=(l+r)>>1;    //建立左子树    buildTree(pos<<1,l,mid);    //建立右子树    buildTree((pos<<1)+1,mid+1,r);} //注意这里的id是info下标,pos是对应树上的位置,顺着pos向下滑动void update(int id,int pos,int dx){    //找到则更新数据    if(tree[pos].l==tree[pos].r)    {        tree[pos].data+=dx;        return;    }    //没找到则继续在左子树或者右子树中找    //说过l,r也是info上的信息,所以要把id和mid相比较    int mid=(tree[pos].l+tree[pos].r)>>1;    if(id<=mid)        update(id,pos<<1,dx);    else        update(id,(pos<<1)+1,dx);    //向上更新一次    tree[pos].data=tree[pos<<1].data+tree[(pos<<1)+1].data;}int query(int l,int r,int pos){    //找到区间返回    if(tree[pos].l==l && tree[pos].r==r)        return tree[pos].data;    int mid=(tree[pos].l+tree[pos].r)>>1;    //看看具体在那个巨剑    if(r<mid)        return query(l,r,pos*2);    else if(l>mid)        return query(l,r,pos*2+1);    else        return query(l,mid,pos*2)+query(mid+1,r,pos*2+1);}int main(){    cin>>n;    int x,y;    memset(ans,0,sizeof(ans));    memset(tree,0,sizeof(tree));    buildTree(1,1,maxn);    while(n--)    {        cin>>x>>y;        ans[query(1,n,x)]++;        update(x,1,1);    }    for(int i=1;i<=n;i++)        cout<<ans[i]<<endl;    return 0;}

0 0
原创粉丝点击