HDU1556 Color the ball 差分模板题

题意:给一段区间的部分染色,统计染色次数。
思路:差分。刚开始我也是感觉用线段树or树状数组做毕竟建树niubility而且lowbit也niubility。但是自从那天限时训练看到bin巨用差分,分分钟就敲出来了,就感觉真尼玛niubility。。。就看了看差分。
我现在所了解的差分就是可以处理区间某段同时加或减去一个数,然后进行查询的一些题目。这题太模板,代码在最后。不过想贴的是两种处理差分的办法:
1、复杂版

		int add=0;
		for(int i=1;i<=n;i++){
			add+=b[i];
			a[i]+=(a[i-1]+add);
		}
		for(int i=1;i<n;i++){
			printf("%d ",a[i]-a[i-1]);
		}printf("%d\n",a[n]-a[n-1]);

2、简单版

		for(int i=1;i<=n;i++){
			a[i]+=(a[i-1]+b[i]);
		}
		for(int i=1;i<n;i++){
			printf("%d ",a[i]);
		}printf("%d\n",a[n]);

两者我对比了一下,发现前者就是多了一个中间变量add,使得a[i]数组最后存的是前缀和,即第一个点到当前点所有染色次数,如果要求当前点的染色次数,那就需要用a[i]-a[i-1]来实现。
而后者就是直接存的当前点的染色次数,不需要再用前缀和来做差求得。
个人觉得两种都有利弊,对于单点查询显然后者好,但是对于区间查询来说,用前缀和作差求区间和显然要比遍历每个节点求和要好。
这就是主要的区别吧,下面上代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define cl(a,b) memset(a,b,sizeof(a))
#define maxn 100005 
using namespace std;
int n;
int a[maxn],b[maxn];
void init(){
	for(int i=1;i<=n;i++){
		a[i]=b[i]=0;
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
		if(n==0) break;
		init();
		for(int i=1;i<=n;i++){
			int l,r;
			scanf("%d%d",&l,&r);
			b[l]++;
			b[r+1]--;
		}
		//————————————方法一 
		int add=0;
		for(int i=1;i<=n;i++){
			add+=b[i];
			a[i]+=(a[i-1]+add);
		}
		for(int i=1;i<n;i++){
			printf("%d ",a[i]-a[i-1]);
		}printf("%d\n",a[n]-a[n-1]);
		/*————————————方法二 
		for(int i=1;i<=n;i++){
			a[i]+=(a[i-1]+b[i]);
		}
		for(int i=1;i<n;i++){
			printf("%d ",a[i]);
		}printf("%d\n",a[n]);
		*/
	}
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值