hdu6315(线段树)

给出一个数组b[i],一个初始为0得a[i],两个操作add l r把a[l] - a[r]都加1,query l r求a[i]/b[i]的和

 

用一个数组维护(a[i] + ti ) / b[i]中的ti, ti初始等于b[i]每add一次ti就减一,当ti为0得时候维护a[i]/b[i]的地方+1,并把ti重置为b[i]

 

下推lazy地时候写错了写成了tree[rt<<1].lazy = tree[rt].lazy,这里应该写+=才对

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define ls rt<<1
#define rs rt<<1|1

const int mx = 1e5+5;
int b[mx],n,q;

struct node
{
	int l, r, sum, min, lazy;
}tree[mx<<2];

void build(int rt,int l, int r)
{
	tree[rt].sum = 0;
	tree[rt].lazy = 0;
	tree[rt].l = l;
	tree[rt].r = r;
	if (l == r)
	{
		tree[rt].min = b[l];
		return ;
	}
	int m = (l + r) / 2;
	build(ls,l,m);
	build(rs,m+1,r);
	tree[rt].min = min(tree[ls].min, tree[rs].min);
}

void PushUp(int rt)
{
	tree[rt].sum = tree[ls].sum + tree[rs].sum;
	tree[rt].min = min(tree[ls].min, tree[rs].min);
}

void PushDown(int rt)
{
	if (tree[rt].lazy)
	{
		tree[ls].min -= tree[rt].lazy;
		tree[rs].min -= tree[rt].lazy;
		tree[ls].lazy += tree[rt].lazy;
		tree[rs].lazy += tree[rt].lazy;
		tree[rt].lazy = 0;
	}
}

void change(int rt)
{
	if (tree[rt].l == tree[rt].r)
	{
		tree[rt].sum++;
		tree[rt].min = b[tree[rt].l];
		return ;
	}
	PushDown(rt);
	if (tree[ls].min == 0)
		change(ls);
	if (tree[rs].min == 0)
		change(rs);
	PushUp(rt); 
}

void update(int l,int r,int rt)
{
	if (tree[rt].l == l && tree[rt].r == r)
	{
		tree[rt].min--;
		tree[rt].lazy++;
		if (tree[rt].min == 0)
			change(rt);
		return ;
	}
	PushDown(rt);
	int m = (tree[rt].l + tree[rt].r) / 2;
	if (m >= r) update(l,r,ls);
	else if (m+1 <= l) update(l,r,rs);
	else
	{
		update(l,m,ls);
		update(m+1,r,rs);
	}
	PushUp(rt);
}

ll query(int rt,int l, int r)
{
	if (tree[rt].l == l && tree[rt].r == r)
		return tree[rt].sum;
	PushDown(rt);
	int m = (tree[rt].l + tree[rt].r) / 2;
	ll ans = 0;
	if (m >= r) ans += query(ls, l, r);
	else if (m+1 <= l) ans += query(rs,l,r);
	else
	{
		ans += query(ls,l,m);
		ans += query(rs,m+1,r);
	} 
	return ans;
}


int main()
{
//	freopen("1007.in","r",stdin);
//	freopen("out.txt","w",stdout);
	while (scanf("%d%d",&n,&q) != EOF)
	{
		memset(b,0,sizeof(b));
		for (int i = 1; i <= n; i++)
			scanf("%d",&b[i]);

		build(1,1,n);
		char op[12];
		int x, y;
		for (int i = 1; i <= q; i++)
		{
			scanf("%s%d%d",op,&x,&y);
			if (op[0] == 'a') update(x,y,1);
			else printf("%lld\n",query(1,x,y));
		}
	}
	
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值