POJ 3468 A Simple Problem with Integers


分析:这题wa了好多次(看了下discuss好多人也是这样,好题~)。一处是sum值会超int32,要用int64。还有一处是toadd要累加,我不知道是受上一题影响还是怎的..pushdown的时候直接替换了...还有,据说北大oj要用%lld读..

类型:成段更新。容易错. 线段树(貌似这题也能用树状数组做?......)

代码:

//3wa
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

#define MAXN 100002
#define int64 long long
#define lc e<<1
#define rc e<<1|1
struct node{ int l, r, mid, toadd; int64 v; }a[MAXN*4];
int n;
void pushup(int e) { a[e].v=a[lc].v+a[rc].v; }
void pushdown(int e)
{
	int t = a[e].toadd;
	if(t)						//这里是对的
	{
		a[e].toadd=0;
		a[lc].v+=(int64)(a[lc].r-a[lc].l+1)*t;
		a[rc].v+=(int64)(a[rc].r-a[rc].l+1)*t;
//		a[lc].toadd=a[rc].toadd=t;			//增量是累加的。写上一题 hdu1698 Just a Hook 写傻掉了.
		a[lc].toadd+=t;
		a[rc].toadd+=t;
	}
}
void build(int l, int r, int e)
{
	a[e].l=l; a[e].r=r;
	if(l==r) scanf("%lld", &a[e].v);					//这里没用%lld 又wa了一次....
	else
	{
		a[e].mid=l+((r-l)>>1);			//????
		build(l, a[e].mid, lc);
		build(a[e].mid+1, r, rc);
		pushup(e);
	}
}
void update(int L, int R, int add, int l, int r, int e)
{
	if(L<=l && r<=R)
	{
		a[e].v+=(int64)(a[e].r-a[e].l+1)*add;
//		a[e].toadd=add;								//这里也一样!!
		a[e].toadd+=add;
	}
	else
	{
		pushdown(e);
		if(L<=a[e].mid) update(L, R, add, l, a[e].mid, lc);
		if(a[e].mid < R) update(L, R, add, a[e].mid+1, r, rc);
		pushup(e);
	}
}
int64 query(int L, int R, int l, int r, int e)
{
	int64 ret=0;
	if(L<=l && r<=R)
	{
		ret+=a[e].v;
	}
	else 
	{
		pushdown(e);		//查询也要推下去
		if(L<=a[e].mid) ret+=query(L, R, l, a[e].mid, lc);
		if(a[e].mid<R) ret+=query(L, R, a[e].mid+1, r, rc);
		pushup(e);	//不用。
	}
	return ret;
}

int main()
{
	int q;
	scanf("%d%d", &n, &q);
	build(1, n, 1);
	char t[2];
	while(q--)
	{
		int x, y;
		scanf("%s%d%d", t, &x, &y);
		if(t[0]=='Q')
		{
			printf("%lld\n", query(x, y, 1, n, 1));		//poj 用 %lld
		}
		else
		{
			int add; scanf("%d", &add);
			update(x, y, add, 1, n, 1);
		}
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值