HDU 1556 Color the ball (只做区间更新)

来源:互联网 发布:开票软件为什么打不开 编辑:程序博客网 时间:2024/06/05 14:41

思路:本题只做区间更新,而不查询。方法很多,线段树是大才小用,代码长不说,在线地维护区间会TLE。故离线之。

线段树的做法:

<span style="font-size:14px;">#include <bits/stdc++.h>using namespace std;const int MAXN=100000+1000;int st,en,tree[3*MAXN],ans[MAXN],ppp;void update(int l,int r,int rt){    if(st<=l&&r<=en){        tree[rt]++;        return ;    }    int mid=(l+r)/2;    if(st<=mid)        update(l,mid,rt*2);    if(mid<en)        update(mid+1,r,rt*2+1);    return ;}void push_down(int rt){    tree[rt*2]+=tree[rt];    tree[rt*2+1]+=tree[rt];}void dfs(int l,int r,int rt){    if(l==r){        ans[++ppp]=tree[rt];return ;    }    push_down(rt);    int mid=(l+r)/2;    dfs(l,mid,rt*2);    dfs(mid+1,r,rt*2+1);    return ;}int main(){    int n;    while(~scanf("%d",&n),n){        memset(tree,0,sizeof(tree));        for(int i=0;i<n;i++){            scanf("%d%d",&st,&en);            update(1,n,1);        }        ppp=-1;        dfs(1,n,1);        printf("%d",ans[0]);        for(int i=1;i<n;i++)            printf(" %d",ans[i]);        printf("\n");    }}</span><span style="font-size:24px;"></span>

离线扫描线的做法:

<span style="font-size:14px;">#include <bits/stdc++.h>using namespace std;const int MAXN=100000+1000;int st,en,ans[MAXN];int main(){    int n;    while(cin>>n&&n){        memset(ans,0,sizeof(ans));        for(int i=0;i<n;i++){            scanf("%d%d",&st,&en);            ans[st]++;            ans[en+1]--;        }        printf("%d",ans[1]);        for(int i=2;i<=n;i++){            ans[i]+=ans[i-1];            printf(" %d",ans[i]);        }        cout<<endl;    }}</span>


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


0 0