气球涂色,分段更新

来源:互联网 发布:广州沙河网络批发 编辑:程序博客网 时间:2024/05/01 15:56



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
3
1 1
2 2
3 3
3
1 1
1 2
1 3
0
 


Sample Output
1 1 1

3 2 1


解法:

常规的做法很简单,就是把[a,b]闭区间内容所有气球累加1次,但是这样会超时。

可以借用累加的思想,假设数组sum[n+1] 初始化全为0,sum[i](1<=i<=n)就表示[i,n]这个闭区间需要累加或者累减多少次,

例如针对给定的闭区间 [a, b],假设让数组 sum[a]+1,代表的含义就是闭区间[a, n]全都累加1次,这样就把 [b+1, n] 这个 度累加了1次,

所以把需要把 [b+1, n] 再都减去1次,即让sum[b+1]--。最终第i个气球被涂色的次数就是sum[1...i]  (1<=i<=n)累加的结果;

import java.util.Scanner;

public class ColorTheBall {



    private static int N;   //气球个数
    private static int sum[];              //每个球被涂的次数结果
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while((N = scanner.nextInt()) != 0){
            sum = new int[N+1];
            int a,b;
            for (int i = 0; i < N; i++){
                a = scanner.nextInt();
                b = scanner.nextInt();
                sum[a]++;   //a 以后的都加1
                if (b<N) {
                    sum[b+1]--; //b 以后的不应该加1,所以要加1
                }
                
            }
            
            int total = 0;
            for (int i = 1; i <= N; i++) {
                total += sum[i];
                System.out.print(total);
                if (i !=N) {
                    System.out.print(" ");
                }
            }
            System.out.println();
        }
        scanner.close();
    }
}



0 0
原创粉丝点击