树论模版汇总

6 篇文章 0 订阅
2 篇文章 0 订阅

树状数组

一维树状数组

#include<bits/stdc++.h>
#define inf 0x7fffffff
#define LL long long
#define rs register
#define fastOI ios::sync_with_stdio(0)
#define fo(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
const LL maxn=10000;
LL n,a[maxn],c[maxn],s[maxn];
LL lowbit(LL i){
	return (-i)&i;
}

void add(LL i,LL z){
	for(;i<=n;i+=lowbit(i)){
		c[i]+=z;
	}
} 

LL sum(LL i){
	LL s=0;
	for(;i>0;i-=lowbit(i)){
		s+=c[i];
	}
	return s; 
}

LL sum(LL i,LL j)
{
	return sum(j)-sum(i-1); 
}

int main(){
	fastOI; cin>>n;
	for(LL i=1;i<=n;i++){
		cin>>a[i];
		add(i,a[i]);
	} 
	LL x1,x2;
	cin>>x1;
	cout<<sum(x1)<<endl;
	cin>>x1>>x2;
	cout<<sum(x1,x2)<<endl;
	return 0;
}

二维树状数组

#include<bits/stdc++.h>
#define mod 0x3f3f3f3f
#define inf 0x7fffffff
#define LL long long
#define rs register
#define fastOI ios::sync_with_stdio(0)
#define fo(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
LL T,n,m,q,ans,a[5010][5010],c[5010][5010];

LL lowbit(LL i){
	return (-i)&i;
}

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

LL sum(LL x,LL y){
	LL s=0;
	for(LL i=x;i>0;i-=lowbit(i))
	for(LL j=y;j>0;j-=lowbit(j)){
		s+=c[i][j];
    }
	return s; 
}

LL sum(LL sx,LL sy,LL ex,LL ey){
	return sum(ex,ey)-sum(sx-1,ey)-sum(ex,sy-1)+sum(sx-1,sy-1); 
}

int main(){
	fastOI; cin>>T;
    while(T--){
        cin>>n>>m>>q;
        memset(c,0,sizeof(c));
	    for(LL i=1;i<=n;i++)
	    for(LL j=1;j<=m;j++){
	    	cin>>a[i][j];
	    	add(i,j,a[i][j]); 
	    }
        ans=0;
		for(LL i=1;i<=q;i++){
			LL sx,sy,ex,ey; 
			cin>>sx>>sy>>ex>>ey;
			cout<<sum(sx,sy,ex,ey);
		}
        cout<<ans<<endl;
    }
	return 0x0;
}

线段树


#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define LL long long
#define rs register
#define fastOI ios::sync_with_stdio(0)
#define fo(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

using namespace std;
const LL maxn=100005;
LL n,a[maxn];

struct node{ 
	LL l,r,mx;
}tree[maxn*4];

void build(LL k,LL l,LL r){
	tree[k].l=l;
	tree[k].r=r;
	if(l==r){
		tree[k].mx=a[l];
		return;
	}
	LL mid,lc,rc;
	mid=(l+r)/2;
	lc=k*2;
	rc=k*2+1; 
	build(lc,l,mid);
	build(rc,mid+1,r);
	tree[k].mx=max(tree[lc].mx,tree[rc].mx);		
} 

void update(LL k,LL i,LL v){
	if(tree[k].l==tree[k].r&&tree[k].l==i){
		tree[k].mx=v;
		return ;
	} 
	LL mid,lc,rc;
	mid=(tree[k].l+tree[k].r)/2;
	lc=k*2;
	rc=k*2+1;
	if(i<=mid)
		update(lc,i,v); 
	else
		update(rc,i,v);
	tree[k].mx=max(tree[lc].mx,tree[rc].mx);
}

LL query(LL k,LL l,LL r){
	if(tree[k].l>=l&&tree[k].r<=r)
		return tree[k].mx;	
	LL mid,lc,rc;
	mid=(tree[k].l+tree[k].r)/2;
	lc=k*2; rc=k*2+1; LL Max=-inf;
	if(l<=mid)
        Max=max(Max,query(lc,l,r));
	if(r>mid)
        Max=max(Max,query(rc,l,r));
	return Max;
}

void print(LL k){
	if(tree[k].mx){
		cout<<k<<"\t"<<tree[k].l<<"\t"<<tree[k].r<<"\t"<<tree[k].mx<<"\t"<<endl;
		print(k<<1);
		print((k<<1)+1);
	}		
}

int main(){
    fastOI;	LL l,r,i,v;
	cin>>n;
	for(i=1;i<=n;i++)cin>>a[i];
	build(1,1,n);
	print(1);
	cin>>l>>r;
	cout<<query(1,l,r)<<endl;
    cin>>i>>v;
	update(1,i,v);
	cin>>l>>r;
	cout<<query(1,l,r)<<endl;
	return 0;
}

线段树(懒标记)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define LL long long
#define rs register
#define fastOI ios::sync_with_stdio(0)
#define fo(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

using namespace std;
const LL maxn=100005;
LL n,a[maxn];

struct node{ 
	LL l,r,mx,lz;
}tree[maxn*4];

void lazy(LL k,LL v){
	tree[k].mx=v;
	tree[k].lz=v;
}

void pushdown(LL k){
	lazy(2*k,tree[k].lz);
	lazy(2*k+1,tree[k].lz);
	tree[k].lz=-1;
}

void build(LL k,LL l,LL r){
	tree[k].l=l;
	tree[k].r=r;
	tree[k].lz=-1; 
	if(l==r){
		tree[k].mx=a[l];
		return;
	}
	LL mid,lc,rc;
	mid=(l+r)/2;
	lc=k*2; 
	rc=k*2+1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	tree[k].mx=max(tree[lc].mx,tree[rc].mx);	
} 

void update(LL k,LL l,LL r,LL v){
	if(tree[k].l>=l&&tree[k].r<=r)
		return lazy(k,v);
	if(tree[k].lz!=-1) 
		pushdown(k);
	LL mid,lc,rc;
	mid=(tree[k].l+tree[k].r)/2;
	lc=k*2;
	rc=k*2+1;
	if(l<=mid)
		update(lc,l,r,v);
	if(r>mid)
		update(rc,l,r,v);
	tree[k].mx=max(tree[lc].mx,tree[rc].mx);
}

LL query(LL k,LL l,LL r){
	LL Max=-inf;
	if(tree[k].l>=l&&tree[k].r<=r)
		return tree[k].mx;
	if(tree[k].lz!=-1) 
		pushdown(k);
	LL mid,lc,rc;
	mid=(tree[k].l+tree[k].r)/2;
	lc=k*2;  
	rc=k*2+1;
	if(l<=mid)
		Max=max(Max,query(lc,l,r));
	if(r>mid)
		Max=max(Max,query(rc,l,r));
	return Max;
} 

int main(){
	LL l,r,i,v;
	cin>>n;
	for(i=1;i<=n;i++)
		cin>>a[i];
	build(1,1,n);
	cin>>l>>r;
	cout<<query(1,l,r)<<endl;
	cin>>l>>r>>v;
	update(1,l,r,v);
	cin>>l>>r;
	cout<<query(1,l,r)<<endl;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值