提高课:数据结构之树状数组

1,楼兰图腾

cpp 复制代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

typedef long long LL;

const int  N = 200010;

int n;
int a[N];
int tr[N];
int Greater[N], lower[N];

int lowbit(int x)
{
	return x & -x;
}
void add(int x, int c)
{
	for (int i = x; i <= n; i = i + lowbit(i)) tr[i] = tr[i] + c;
}
int sum(int x)
{
	int res = 0;
	for (int i = x; i; i = i - lowbit(i))res = res + tr[i];
	return res;
}
int main()
{
	cin >> n;

	for (int i = 1; i <= n; i++)cin >> a[i];

	for (int i=1; i <= n; i++)
	{
		int y = a[i];
		Greater[i] = sum(n) - sum(y);
		lower[i] = sum(y - 1);
		add(y, 1);
	}
	memset(tr, 0, sizeof(tr));
	LL res1 = 0, res2 = 0;
	for (int i = n; i; i--)
	{
		int y = a[i];
		res1 += Greater[i] * (LL)(sum(n) - sum(y));
		res2 += lower[i] * (LL)(sum(y-1));
		add(y, 1);
	}

	cout << res1 << " " << res2 << endl;
	return 0;
	//5
	//1 5 3 2 4
	//3 4
	
}
cpp 复制代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

typedef long long LL;

const int  N = 1e5 + 10;
int n;
int a[N];
long long tr[N];//表示区间总和//也相当于N代表方块
int G[N];

int lowbit(int x)
{
	return x & (-x);
}//查找子叶个数

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

}//如上

long long sum(int x)//前x项的和
{
	long long res = 0;
	for (int i = x; i; i -= lowbit(i)) res += tr[i];
	return res;
}//如上

int main()
{
	cin >> n;

	for (int i = 1; i <= n; i++)cin >> a[i];

	for (int i = 1; i <= n; i++)
	{

		for (int k = 0; k <= n + 1; k++)
		{
			cout << tr[k];
		}
		cout << endl;

		for (int k = 0; k <= n + 1; k++)
		{
			cout << G[k];
		}
		cout << endl;

		int y = a[i];
		G[i] = sum(n) - sum(y);
		add(y, 1);
	}

		for (int k = 0; k <= n+1; k++)
		{
			cout << tr[k];
		}
		cout << endl;

		for (int k = 0; k <= n+1; k++)
		{
			cout << G[k];
		}
		cout << endl;

	memset(tr, 0, sizeof tr);
	cout << "--------------" << endl;
	LL res1 = 0;
	for (int i = n; i; i--)
	{
		int y = a[i];
		res1 += G[i] * (LL)(sum(n) - sum(y));
		add(y, 1);

		for (int k = 0; k <= n; k++)
		{
			cout << tr[i];
		}
		cout << endl;

		for (int k = 0; k <= n; k++)
		{
			cout << G[i];
		}
		cout << endl;

	}
	cout << res1 << endl;
	return 0;
}
cpp 复制代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

const int  N = 1e5 + 10;
int n;
int a[N];
long long tr[N];//表示区间总和

int lowbit(int x)
{
	return x & (-x);
}//查找子叶个数

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

}//如上

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

int main()
{
	while (cin>>n)
	{
		if (!n)break;
		//memset(a,0,sizeof(a));
		memset(tr, 0, sizeof(tr));
		for (int k = 1; k <= n; k++)
		{
			int l, r;
			
			cin >> l >> r;

			//		for(int i=l;i<=r;i++)
			//		{
			//			
			//		}
			//int yy = l - r + 1;
			add(l, 1);
			add(r + 1, -1);
		}

		for (int i = 1; i < n; i++)
		{
			cout << sum(i) << " ";
		}
		cout<< sum(n) << endl;

	}
	return 0;
}
cpp 复制代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

const int  N = 1e6 + 5;
int n,m;
int a[N];
long long tr[N];//表示区间总和

int lowbit(int x)
{
	return x & (-x);
}//查找子叶个数

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

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

int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &a[i]);
		add(i, a[i]);//传参
	}
	while (m--)
	{
		int x, y, z;
		scanf("%d %d %d", &x, &y, &z);
		if (x == 1)
		{
			add(y, z);
		}
		if (x == 2)
		{
			long long sum1 = sum(y - 1);
			long long sum2 = sum(z);
			printf("%lld\n", sum2 - sum1);//前缀和公式
		}
	}
	return 0;
	//5
	//1 5 3 2 4
	//3 4
	
}
cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

typedef long long LL;

const int N = 100010;

int n, m;
int a[N];
int tr11[N];
int tr2[N];

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

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

}

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

LL prefix_sum(int x)
{
	return sum(tr11, x) * (x + 1) - sum(tr2, x);
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)cin >> a[i];
	for (int i = 1; i <= n; i++)
	{
		int b = a[i] - a[i - 1];
		add(tr11, i, b);
		add(tr2, i, (LL)b*i);
	}
	while (m--)
	{
		char op[2];
		int l, r, d;
		cin >> op >> l >> r;
		if (*op == 'Q')
		{
			cout << prefix_sum(r) - prefix_sum(l - 1) << endl;
		}
		else
		{
			cin >> d;
			add(tr11, l, d), add(tr2, l, l * d);
			add(tr11, r + 1, -d), add(tr2, r + 1, (r + 1) * -d);
		}
	}
	return 0;
	//10 5
	//1 2 3 4 5 6 7 8 9 10
	//Q 4 4
	//Q 1 10
	//Q 2 4
	//C 3 6 3
	//Q 2 4

	//4
	//55
	//9
	//15
}
相关推荐
王璐WL1 天前
【C++】类的默认成员函数(上)
c++
Robot_Nav1 天前
TD3 —— 双延迟深度确定性策略梯度算法文献解读
算法·td3·drl
斯维赤1 天前
每天学习一个小算法:归并排序
学习·算法·排序算法
王老师青少年编程1 天前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:区间覆盖(加强版)
c++·算法·贪心·csp·信奥赛·区间贪心·区间覆盖(加强版)
碧海银沙音频科技研究院1 天前
杰理项目开发大全课程
人工智能·深度学习·算法
宏笋1 天前
C++11完美转发的作用和用法
c++
格发许可优化管理系统1 天前
MathCAD许可类型全面解析:选择最适合您的许可证
c++
风一样的航哥1 天前
LeetCode 2615 等值距离和:前缀和优化O(n)解法深度解析
数据结构·算法·leetcode
生成论实验室1 天前
生成态势猜想:一种统一的宇宙动力学语法
人工智能·科技·神经网络·算法·信息与通信
旖-旎1 天前
深搜(二叉树的所有路径)(6)
c++·算法·leetcode·深度优先·递归