hdu - 1556 (Color the ball 线段树)

来源:互联网 发布:海岛奇兵升级数据2017 编辑:程序博客网 时间:2024/05/16 17:14

题目链接:点击打开链接

思路:简单的线段树模板,理解了好久。创建+更新+查询。更新只涉及到区间更新次数(+1)即可。查询可以递归查询,累加包含查询结点的树结点(即离散化的区间[l,r])的次数即可。简单的说就是,查询结点所在的区间更新次数的总和。

eg:离散化到树结点,若共有4个结点,更新区间[1,3]则更新到区间[1,2]+[3,3].

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;struct Node{    int l,r;    int sum;        //sum表示整个区间 [l,r] 被维护的次数。一定是整个区间,且被离散化到各个树结点的子区间}node[400005];void build(int id,int l,int r){    node[id].l = l;    node[id].r = r;    node[id].sum = 0;    if(l == r)        return ;    int mid = (l+r) >> 1;    build(id*2,l,mid);    build(id*2+1,mid+1,r);}void update(int id,int l,int r){    if(node[id].l == l && node[id].r == r){        node[id].sum++;        return ;    }    int mid = node[id].l+node[id].r >> 1;    if(r <= mid)   update(id*2,l,r);    else if(l > mid)        update(id*2+1,l,r);    else{        update(id*2,l,mid);        update(id*2+1,mid+1,r);    }}int ans;void query(int id,int temp){    ans += node[id].sum;    if(node[id].l == node[id].r && node[id].l == temp)        return ;    int mid = (node[id].l + node[id].r) >> 1;    if(temp <= mid) query(2*id,temp);    else        query(2*id+1,temp);}int main(){    int n;    while(cin>>n,n != 0){        int l,r;        build(1,1,n);        for(int i = 1;i <= n;i ++){            scanf("%d%d",&l,&r);            update(1,l,r);        }        for(int i = 1;i <= 15;i ++)            cout<<node[i].l<<"  "<<node[i].r<<"  "<<node[i].sum<<endl;        for(int i = 1;i <= n;i ++){            if(i != 1)  cout<<" ";            ans = 0;            query(1,i);            cout<<ans;        }        cout<<endl;    }    return 0;}


0 0