2020寒假集训专题五 POJ 3468 A Simple Problem with Integers(树状数组解法)

原题链接:http://poj.org/problem?id=3468
专题链接:https://vjudge.net/contest/352439#problem/B

思路


本来是线段树的板子,奈何线段树太难打,头铁学了个树状数组来区间操作区间查询的方法

代码如下:

#include<iostream>
#include<cstdio>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
int N, Q;
ll arr[100001];
ll sum[100001];
ll tem[2][100001];
void update(int i, ll n,int flag)
{
	while (i <= N)
	{
		tem[flag][i] += n;
		i += lowbit(i);
	}
}
ll get_sum(int i, int flag)
{
	ll ans=0;
	while (i)
	{
		ans += tem[flag][i];
		i -= lowbit(i);
	}
	return ans;
}
int main()
{
	cin >> N >> Q;
	for (int i = 1; i <= N; i++)
	{
		scanf("%lld", &arr[i]);
		sum[i] = sum[i - 1] + arr[i];
	}
	while (Q--)
	{
		char t;
		ll l,r ;
		scanf(" %c%lld%lld", &t, &l, &r);
		if (t == 'C')
		{
			ll t1;
			scanf("%lld", &t1);
			update(l,t1,0);//差分思路
			update(r+1,-t1,0);
			update(l,t1*l,1);
			update(r + 1, -t1 * (r + 1), 1);
		}
		else
		{
			ll ans=0;
			ans += sum[r] + get_sum(r, 0) * (r + 1) - get_sum(r, 1);//第二项要*(i+1)
			ans -= sum[l - 1] + get_sum(l - 1, 0) * l - get_sum(l-1, 1);
			printf("%lld\n", ans);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值