如何存储数组的每个相邻子数组的和
How to store the sum of every contigous subarray of an array?
我有一个n个元素的数组(1 <= n <= 200000)。我要找出这个数组中所有相邻子数组的和。我有一个O(n^2)的算法可以找到所有的和,但我的问题是我不能把它存储在任何数据结构中因为有n(n+1)/2个元素。因此将有10^10个元素,这将需要很大的空间。这是我得到的输出。
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
我猜是因为我的代码使用了太多的内存。以下是我的代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define vi vector<int>
#define vli vector<lli>
#define dqi deque<int>
#define MOD 10e9+7
#define mis map<int,string>
#define msi map<string,int>
#define set0(a) memset(a,0,sizeof(a))
#define sc scanf
#define pr printf
#define rint(a) sc("%d",&a)
#define rchar(a) sc("%d",&a)
#define pb push_back
#define pf push_front
#define rstring(s) sc("%s",&s)
#define rp(a,b,c) for(int (a)=(b);(a)<(c);(a)++)
#define rpn(a) while(a--)
int a[200010],t=0,n=0,q=0,cnt=0;
vector<long long int> b;
long long int l=0,r=0;
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
memset(a,0,sizeof(a));
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&q);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
long long int sum=0;
for(int i=n-1,j=1;i>=0;i--,j++){
b.push_back(a[i]);sum=a[i];
for(int j=i+1;j<=n-1;j++)
b.push_back(sum+=a[j]);
}
//following part find the sum of elements of subarrays in a given range after sorting them
printf("Case #%d: n",++cnt);
while(q--){
scanf("%lld %lld",&l,&r);
long long int sum=0;
for(long long int i=l-1;i<r;i++)
sum+=b[i];
printf("%lldn",sum);
}
b.clear();
}
return 0;
}
还有别的方法吗?请指导。
您可以使用通常用于这类问题的段树。浏览下面的链接
https://www.hackerearth.com/practice/notes/segment-tree-and-lazy-propagation/
可以将元素的和存储在根目录中,而不是给定的两个元素的差值(在链接中给出)。
您正在获得'std::bad_alloc',因为您试图分配如此多的静态内存。静态内存的分配是有限制的,这取决于环境:您在哪个操作系统中运行它?那是16位、32位、64位的内存架构吗?更多信息。
<交替方式/h4>
另一种方法需要O(n)个时间和O(n)个辅助空间。你不需要计算每个连续子数组的和。相反,计算并存储到初始数组的第i个元素的和到一个新数组中。
如果初始数组(A)为[5,3,9,15,21],则新数组(B)将为[5,8,17,32,53]。
无论何时你需要连续子数组[l, r](包括两个)的和,其中l是左索引(或开始索引),r是右索引(或结束索引),你可以在O(1)时间内得到它,这个和将等于B[r] - B[l] + A[l]
下面是相同的实现。
# include <bits/stdc++.h>
using namespace std;
int main() {
long long n; // number of elements in the array
cin >> n;
vector<long long> A(n), B(n); // A is the initial array (array with no modifications)
// B is the calculated array (ith element of B contains sum up to the ith element of A)
for (long long i = 0; i < n; i++) {
cin >> A[i];
if (i == 0) {
B[i] = A[i];
}
else {
B[i] = A[i] + B[i - 1];
}
}
int q; // number of queries
cin >> q;
while (q--) {
int l, r; // l is the left index (or starting index, zero based)
// r is the right index (or ending index, zero based)
cin >> l >> r;
cout << (B[r] - B[l] + A[l]) << endl; // sum of contiguous subarray [l, r] (both inclusive)
}
return 0;
}
相关文章:
- 使用无符号字符数组有效存储内存
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 如何在二维数组中存储值?
- 拆分字符数组并存储为向量
- C++:矩阵高斯消除不起作用:使用单维数组来存储元素
- CUDA 数组如何存储在 GPU 内存中?它们在物理上是线性的吗?
- 数组中存储的整数的旋转
- 在字符数组中存储和恢复一组单词
- 没有带有字符串数组的存储类或类型说明符
- 如何在 BaseClass 指针数组中存储指向子类对象的指针?
- 如何在不知道Arduino中知道其大小的情况下创建数组和存储值
- 发出阅读文件,并使用数组正确存储和检查内容
- 如何知道我想在数组中存储多少索引
- 在未分配某些元素的数组中存储了什么值
- 我如何在2D数组中存储许多精灵
- 如何在整数数组中存储字符
- 在C 中的数组中存储抽象基类的不同派生类的对象
- 创建一个动态2D数组来存储类对象
- 我在使用 cin.getline() 从用户那里获取 3 个字符串并使用指针数组来存储它们时遇到问题
- 字符数组如何存储在内存中?