差分标记-HDU1556 Color the ball

时间:2022-07-25
本文章向大家介绍差分标记-HDU1556 Color the ball,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

文章目录

  • 差分标记
  • 例题
    • 分析
    • 代码
  • 小结

差分标记


什么是差分标记? 差分标记,是一种和前缀和相对的离线算法。 所谓差分就是将数组a每一项与前一项做差,记作差分数组b,易得对数组b做一遍前缀和就得到了原来的a数组。 因为是离线算法所以修改操作一定要在查询操作之前,它可以维护多次对序列的一个区间加减上一个数,最后询问某一位的数。

例题


传送门: HDU-1556

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值全为0,那么相应差分数组b也初始化0即可。每次修改区间[x,y]值加1,那么差分数组b更新b[x]++,b[y+1]–即可,最后循环前缀和还原数组a并输出。

代码

#include<cstdio>
#include<string.h>
using namespace std;
const int maxn = 100005;
int b[maxn];
int main() {
	int x, y, n;
	while (~scanf("%d", &n) && n) {
		memset(b, 0, sizeof(b));
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &x, &y);
			b[x]++;//更新差分数组b的区间[x,y]
			b[y + 1]--;
		}
		int ans = 0;
		for (int i = 1; i < n; i++) {
			ans += b[i];//前缀和还原数组a
			printf("%d ", ans);
		}
		ans += b[n];
		printf("%dn", ans);//输出末尾换行处理
	}
	return 0;
}

小结


  1. 相对于线段树/数组数组而言,差分代码简短易写能节省大量时间。
  2. 差分标记只适用于离线的区间修改问题,如果是在线(边改边查)的话应该用线段树或树状数组等。

原创不易,请勿转载本不富裕的访问量雪上加霜 ) 博主首页:https://blog.csdn.net/qq_45034708