[HDU-1698] Just a Hook题解(区间覆盖+区间查询)

知识点:
线段树(区间覆盖+区间查询)

#include<cstdio>
using namespace std;
typedef long long ll;
struct tree{
	int data;
	int tag;
}tr[800600];
ll n,q,cas;
void bud_tr(ll r,ll lf,ll rg){
	tr[r].tag=0;
	if(lf==rg){
		tr[r].data=1;(全部赋值为1return ;
	}
	ll lf_r=2*r;
	ll rg_r=2*r+1;
	ll mid=(lf+rg)/2;
	bud_tr(lf_r,lf,mid);
	bud_tr(rg_r,mid+1,rg);
	tr[r].data=tr[lf_r].data+tr[rg_r].data;
}
void change(ll r,ll lf,ll rg,ll k){
	tr[r].data=k*(rg-lf+1);(直接覆盖就好)
	tr[r].tag=k;
}
void push_down(ll r,ll lf,ll rg){
	if(tr[r].tag==0)return ;(注意,这个一定要加上,要考虑当前tag为0的情况,不然的话会覆盖为0,当然其实一开始令所有tag为1也行,但是这样的话重复执行耗费时间)
	ll mid=(lf+rg)/2;
	change(2*r,lf,mid,tr[r].tag);
	change(2*r+1,mid+1,rg,tr[r].tag);
	tr[r].tag=0;
}
void update(ll r,ll srt,ll edi,ll lf,ll rg,ll k){
	if(lf<=srt&&edi<=rg){(在区间内则进行覆盖)
		change(r,srt,edi,k);
		return ;
	}
	ll lf_r=2*r;
	ll rg_r=2*r+1;
	ll mid=(srt+edi)/2;
	push_down(r,srt,edi);
	if(lf<=mid)update(lf_r,srt,mid,lf,rg,k);
	if(mid<rg)update(rg_r,mid+1,edi,lf,rg,k);
	tr[r].data=tr[lf_r].data+tr[rg_r].data;
}
int main(){
	scanf("%lld",&cas);
	ll i,j,n,m,x,y,k;

	for(i=1;i<=cas;i++){
		scanf("%lld",&n);
		for(j=1;j<=4*n+30;j++)(注意,这里不能用memset,不然会WA!)
		 tr[j].data=tr[j].tag=0;
		bud_tr(1,1,n);

		scanf("%lld",&m);
		for(j=1;j<=m;j++){
			scanf("%lld%lld%lld",&x,&y,&k);
			update(1,1,n,x,y,k);
		}
		printf("Case %lld: The total value of the hook is %lld.\n",i,tr[1].data);
	}
}

总结:其实和普通的线段树没太大区别,就是改一改而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值