poj 3468 线段树成段增减+区间求和 ʕ •ᴥ•ʔ

POJ 3468 A Simple Problem with Integers 

给出了一个序列,你需要处理如下两种询问。

"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。

"Q a b" 询问[a, b]区间中所有值的和。

Input

第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.

第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。

接下来Q行询问,格式如题目描述。

Output

对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。

Sample Input

 
  1. 10 5

  2. 1 2 3 4 5 6 7 8 9 10

  3. Q 4 4

  4. Q 1 10

  5. Q 2 4

  6. C 3 6 3

  7. Q 2 4

Sample Output

 
  1. 4

  2. 55

  3. 9

  4. 15

 这道题有两种方法: 线段树和树状数组都可以 小编先用代码比较少的树状数组的来写 后期会把线段树的补上

树状数组 代码:

 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define N 100010
#include<map>
#define ll long long 
using namespace std;
/*

sum(1~k) 1到k项的和  
sum(1~k)=c1+(c1+c2)+(c1+c2+c3)+....+(c1+c2+c3+..cn);
=k*c1+(k-1)*c2+(k-2)*c3+....cn
通项 (k-i+1)*ci 
拆分   tree1 (k+1)ci tree2 i*ci
 
*/ 
ll n,m;
ll sum[100010];
ll tree1[100010],tree2[100010];
ll lowbit(ll w)
{
	return w&-w;
}
ll add(ll w,ll x,ll *tree)
{
	while(w<=n)
	{
		tree[w]+=x;
		w+=lowbit(w);
	} 
}
ll Query(ll w,ll *tree)
{
	ll ans=0;
	while(w>0)
	{
		ans+=tree[w];
		w-=lowbit(w);
	}
	return ans;
}
int main()
{
	std::ios::sync_with_stdio(false);//需要加速 不然会 runtime 
	cin>>n>>m;
	
	memset(sum,0,sizeof(sum));
	memset(tree1,0,sizeof(tree1));
	memset(tree2,0,sizeof(tree2));
	for(ll i=1;i<=n;i++)
	{
		cin>>sum[i];
		sum[i]=sum[i]+sum[i-1];
	}
	
	for(ll i=0;i<m;i++)
	{
		char ch;
		cin>>ch;
		if(ch=='Q')
		{
			ll a,b;
			cin>>a>>b;
			ll ans=sum[b]-sum[a-1];
			ans+=(b+1)*(Query(b,tree1))-(a)*(Query(a-1,tree1));//添加
			 
			ans=ans-((Query(b,tree2))-(Query(a-1,tree2)));//减少 
			cout<<ans<<endl;
		}
		else if(ch=='C')
		{
			ll a,b,x;
			cin>>a>>b>>x;
			add(a,x,tree1);// 添加 
			add(b+1,-x,tree1); 
			
			add(a,a*x,tree2);// 减少 
			add(b+1,-(b+1)*x,tree2);
		}
	}
	return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值