2019东北四省 H. Skyscraper (树状数组)

传送门

我菜逼我不会写,看了题解,喵啊。

题意:

思路:


#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define SZ(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define drep(i,a,b)	for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-9;
const int maxn=1e6+6;
ll T,n,m,a[maxn],b[maxn];
struct tr {
	ll sum[maxn];
	void add(int p,int x) {
		while(p<=n+2)	sum[p]+=x,p+=p&-p;
	}
	ll ask(int p) {
		ll res=0;
		while(p)	res+=sum[p],p-=p&-p;
		return res;
	}
	ll r_ask(int l,int r) {
		return ask(r)-ask(l-1);
	}
} tb,tc;
int main() {
	std::ios::sync_with_stdio(0);
	cin>>T;
	while(T--) {
		cin>>n>>m;
		rep(i,1,n) {
			cin>>a[i];
			if(i>=2) {
				b[i]=a[i]-a[i-1];
				tb.add(i,b[i]);
				if(b[i]>0) tc.add(i,b[i]);
			} 
			else {
				b[i]=a[i];
				tb.add(i,a[i]);
				tc.add(i,a[i]);
			}
		}
		int op,l,r,x;
		rep(i,1,m) {
			cin>>op;
			if(op==1) {
				cin>>l>>r>>x;
				tb.add(l,x),tb.add(r+1,-x);
				if(b[l]>0) 	tc.add(l,x);
				else if(b[l]+x>0) tc.add(l,b[l]+x);
				
				if(b[r+1]>0) {
					if(b[r+1]-x>0) 	tc.add(r+1,-x);
					else	tc.add(r+1,-b[r+1]);
				}
				b[l]+=x,b[r+1]-=x;
			}
			else {
				cin>>l>>r;
				cout<<tb.r_ask(1,l)+tc.r_ask(l+1,r)<<endl;
			}
		}
		rep(i,1,n+5) tb.sum[i]=0,tc.sum[i]=0;
	}
	return 0;
}








 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值