树状数组模板(C/C++)

注意:数组的长度不满足题意,仅提供模板!!

目录

样题1:修改单点值+输出区间和

 样题2:修改区间值+输出单点和

 样题3:求逆序对

样题4:求区间最值


样题1:修改单点值+输出区间和

树状数组模板(C/C++)_第1张图片树状数组模板(C/C++)_第2张图片 代码:

#include
#define lowbit(x) (x&(-x))
typedef long long ll; 
using namespace std;
int c[100];
int n,m;
ll ans;
int add_dandian(int x,int k)//单点修改值 
{
	for(int i=x;i<=n;i+=lowbit(i))  c[i]+=k;
}
int search(int begin,int end)//求区间和 
{
	for(int i=end;i;i-=lowbit(i))  ans+=c[i];
	for(int i=begin-1;i;i-=lowbit(i))  ans-=c[i];
	return 0;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)//初始化数组 
	{
		int number;
		cin>>number;
		add_dandian(i,number);
	}
	for(int i=1;i<=m;i++)
	{
		int choice,x,y;
		cin>>choice>>x>>y;
		if(choice==1) add_dandian(x,y);//在第x个数上加上k 
		else
		{
			ans=0;
			search(x,y);
			cout<

 样题2:修改区间值+输出单点和

树状数组模板(C/C++)_第3张图片树状数组模板(C/C++)_第4张图片 代码:

#include
#define lowbit(x) (x&(-x)) 
using namespace std;
typedef long long ll;
int a[100];
int d[100];//d[i]的值,d[i]表示第i和i-1个数的差值
ll c[100]; 
int n,m;
int update(int pos,int k)//pos表示修改点的位置,K表示修改的值也即+K操作
{
	for(int i=pos;i<=n;i+=lowbit(i))  c[i]+=k;
}
ll ask_qujian(int pos)//返回区间pos到1的总和
{
	ll ans=0;
	for(int i=pos;i;i-=lowbit(i)) ans+=c[i];
	return ans;
} 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)//初始化数组 
	{
		cin>>a[i];
		d[i]=a[i]-a[i-1];//d[i]的值,d[i]表示第i和i-1个数的差值
		update(i,d[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int choice,x,y,k;
		cin>>choice;
		if(choice==1)
		{
			cin>>x>>y>>k;
			update(x,k);
			update(y+1,-k);
		}
		else
		{
			cin>>x;
			cout<

 样题3:求逆序对

树状数组模板(C/C++)_第5张图片代码:

#include
using namespace std;
#define lowbit(x) x&(-x)
int t[100]; 
typedef struct node
{
   int val,ind;
}Node;
Node stu[100];
int Rank[100];
typedef long long ll;
int n; 

/*单点修改*/
void add(int pos)
{
	for(int i=pos;i<=n;i+=lowbit(i)) t[i]+=1;
}
/*区间求和*/
int ask(int pos)
{
	int ans = 0; 
	for(int i=pos;i;i-=lowbit(i)) ans+=t[i];
	return ans;
} 
/*不能单纯的a.val>n;
	for(int i=1;i<=n;i++)
	{
		cin>>stu[i].val;
		stu[i].ind=i;
	}
	sort(stu+1,stu+n+1,cmp);
	/*离散化操作*/
	for(int i=1;i<=n;i++)
	{
		Rank[stu[i].ind] = i;
	} 
	for(int i=1;i<=n;i++)
	{
		int pos = Rank[i];
		ans+=ask(n)-ask(pos);//digit+1~n中有多少数字已经出现就贡献多少逆序对数,累加到答案 
		add(pos);//单点修改
	}
	cout<

样题4:求区间最值

最大值

#include 
using namespace std;
#define lowbit(x) x&(-x)
int a[10]={1,10,5,3,15,14,13,10,-5000,4};
int query(int x, int y)
{
	int ans = 0;
	while (y >= x)
	{
		ans = max(a[y], ans);
		y --;
		for (; y-lowbit(y) >= x; y -= lowbit(y))
			ans = max(a[y], ans);
	}
	return ans;
}
int main()
{
	cout<

最小值

#include 
using namespace std;
#define lowbit(x) x&(-x)
int a[10]={1,10,5,3,15,14,13,10,-5000,4};
int query(int x, int y)
{
	int ans = INT_MAX;
	while (y >= x)
	{
		ans = min(a[y], ans);
		y --;
		for (; y-lowbit(y) >= x; y -= lowbit(y))
			ans = min(a[y], ans);
	}
	return ans;
}
int main()
{
	cout<

背记诀窍:

树状数组模板(C/C++)_第6张图片

你可能感兴趣的:(算法,蓝桥杯,C/C++,树状数组,lowbit)