HUEL_ACM第二学期第三周:树状数组

A

#include <iostream>
#include <cstring>
#include <algorithm>
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define endl '\n'
#define int long long
using namespace std; 
const int N=1e5+6;
int n,a[N],tr[N];
int lowbit(int x){
	return x&-x;
}

int add(int x,int c){
	for(int i=x;i<=n;i+=lowbit(i))tr[i]+=c;
}
int sum(int x){
	int res=0;
	//cout<<x<<"****"<<endl;
	for(int i=x;i;i-=lowbit(i)){
		res+=tr[i];
		
	}
	return res;
}
main(){
	int T;
	scanf("%lld",&T);
	for(int TT=1;TT<=T;TT++){
		memset(tr,0,sizeof tr);
		printf("Case %d:\n",TT);
		scanf("%lld",&n);
		for(int i=1;i<=n;i++){
			cin>>a[i];
			add(i,a[i]);
		}
		
		string s;
		int l,r;
	    while(cin>>s,s!="End"){
			scanf("%lld%lld",&l,&r);
			if(s=="Add")add(l,r);
			else if(s=="Sub")add(l,-r);
			else printf("%lld\n",sum(r)-sum(l-1));
	  	}
	} 
}

B

#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio;cin.tie(0); 
using namespace std;
const int N=1100;
int n,tr[N][N];

int lowbit(int x){
	return x&-x;
}

void add(int x,int y,int c){
	for(int i=x;i<=n;i+=lowbit(i))
	for(int j=y;j<=n;j+=lowbit(j))
	tr[i][j]+=c;
}

int sum(int x,int y){
	int res=0;
	for(int i=x;i;i-=lowbit(i))
	for(int j=y;j;j-=lowbit(j))
	res+=tr[i][j];

	return res;
}

main(){
	IOS;
	int op;
	while(cin>>op){
		if(op==3)break;
		else if(op==0)cin>>n;
		else if(op==1){
			int x,y,a;
			cin>>x>>y>>a;
			x++,y++;
			add(x,y,a);
		}
		else if(op==2){
			int x1,y1,x2,y2;
			cin>>x1>>y1>>x2>>y2;
			x1++,y1++,x2++,y2++;
			cout<<sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1)<<endl;
		}
	}
}

C

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int N=1e6+5;
int n,a[N],b[N];
int tr[N];

int lowbit(int x){
	return x&-x;
}

void add(int x,int k){
	for(int i=x;i<=n;i+=lowbit(i))tr[i]+=k;
}

int sum(int x){
	int res=0;
	for(int i=x;i;i-=lowbit(i))res+=tr[i];
	return res;
} 

main(){
	while(scanf("%lld",&n),n){
		memset(tr,0,sizeof tr);
		
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
			b[i]=a[i];
		}
		
		sort(b+1,b+1+n);
		for(int i=1;i<=n;i++){
			int hash=lower_bound(b+1,b+1+n,a[i])-(b+1)+1;
			a[i]=hash;
		}
		
		int res=0;
		for(int i=1;i<=n;i++){
			//add(a[i],1);
			//cout<<sum(n)<<"***"<<sum(a[i])<<endl;
			res+=sum(n)-sum(a[i]);
			add(a[i],1);
		}
		printf("%lld\n",res);	
	}
}

D

#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int N=1e5+6;
int n,m;
int a[N],b[N];
int tr1[N],tr2[N];

int lowbit(int x){
	return x&-x;
}

void add1(int x,int c){
	for(int i=x;i<=n;i+=lowbit(i))tr1[i]+=c;
}

void add2(int x,int c){
	for(int i=x;i<=n;i+=lowbit(i))tr2[i]+=c;
}

int sum1(int x){
	int res=0;
	for(int i=x;i;i-=lowbit(i))res+=tr1[i];
	return res;
}

int sum2(int x){
	int res=0;
	for(int i=x;i;i-=lowbit(i))res+=tr2[i];
	return res;
}

main(){
	int T;
	scanf("%lld",&T);
	while(T--){
		memset(tr1,0,sizeof tr1);
		memset(tr2,0,sizeof tr2);
		
		scanf("%lld%lld",&n,&m);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		
		for(int i=1;i<=n;i++){
			b[i]=a[i]-a[i-1];
			add1(i,b[i]);
			if(b[i]>0)add2(i,b[i]);
		}
		
		while(m--){
			int op;
			scanf("%lld",&op);
			if(op==1){
				int l,r,k;
				scanf("%lld%lld%lld",&l,&r,&k);
				//b[l]+=k,b[r+1]-=k;
				add1(l,k),add1(r+1,-k);
				
				if(b[l]<0){
					if(b[l]+k>0)add2(l,b[l]+k);
				}
				else add2(l,k);
				
				if(b[r+1]>=0){
					if(b[r+1]-k>=0)add2(r+1,-k);
					else add2(r+1,-b[r+1]);
				} 
				
				b[l]+=k,b[r+1]-=k;
			}
			else{
				int l,r;
				scanf("%lld%lld",&l,&r);
				printf("%lld\n",sum1(l)+sum2(r)-sum2(l));
			}
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值