hdu 1556 Color the ball

来源:互联网 发布:c#高级编程第10版 编辑:程序博客网 时间:2024/06/06 19:11
Problem Description
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
 

Input
每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
当N = 0,输入结束。
 

Output
每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
 

Sample Input
31 12 23 331 11 21 30
 

Sample Output
1 1 13 2 1
思路:树状数组或者线段树都可以做,如果不知道树状数组或者线段树是什么,网上可以搜到很多,个人觉得树状数组处理的是单点修改和区间求和,线段树则具备了树状数组的特性,并且支持区间修改值和区间求和,主要是回溯处理吧,很奇妙的东西
代码:
树状数组版:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <vector>#include <queue>#include <cstdlib>#include <string>#include <set>#include <stack>using namespace std;const int maxn = 100100;int num[maxn];int lowbit(int x){    return x&(-x);}void update(int x,int a){    while(x){        num[x] += a;        x -= lowbit(x);    }}int getsum(int x,int n){    int sum = 0;    while(x<=n){        sum += num[x];        x += lowbit(x);    }    return sum;}int main() {    int n,a,b;    while(~scanf("%d",&n)&&n) {        memset(num,0,sizeof(num));        for(int i = 0; i < n; ++i) {            scanf("%d%d",&a,&b);            update(b,1);            update(a-1,-1);        }        printf("%d",getsum(1,n));        for(int i = 2;i<= n;++i){            printf(" %d",getsum(i,n));        }        printf("\n");    }    return 0;}


线段树版本:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <vector>#include <queue>#include <cstdlib>#include <string>#include <set>#include <stack>using namespace std;const int maxn = 100100;struct point {    int left;    int right;    int add;} node[maxn*4];void bulidtree(int now,int l,int r) {    node[now].left = l;    node[now].right = r;    node[now].add = 0;    if(l == r) {        return;    }    bulidtree(now<<1,l,(l+r)/2);    bulidtree(now<<1|1,(l+r)/2+1,r);}void update(int now,int l,int r) {    if(l == node[now].left && r == node[now].right) {        node[now].add += 1;        return;    }    if(r <= node[now<<1].right) {        update(now<<1,l,r);    }    else if(l >= node[(now<<1)+1].left) {        update((now<<1)+1,l,r);    }    else {        update(now<<1,l,node[now<<1].right);        update(now<<1|1,node[now<<1|1].left,r);    }}void query(int now,int sum) {    if(node[now].left == node[now].right) {        if(node[now].right == 1) {            printf("%d",sum+node[now].add);        } else {            printf(" %d",sum+node[now].add);        }        return;    }    query(now<<1,sum+node[now].add);    query(now<<1|1,sum+node[now].add);}int main() {    int n;    while(~scanf("%d",&n)&&n) {        int a,b;        bulidtree(1,1,n);        for(int i = 0; i < n; ++i) {            scanf("%d%d",&a,&b);            update(1,a,b);        }        query(1,0);        printf("\n");    }    return 0;}
总结:自己对这两种数据结构的做法理解还不是很透彻,这是两种很每秒的数据结构

0 0
原创粉丝点击