第1行:一个数N,N为数组的长度(2 <= N <= 50000)。 第2 至 N + 1行:数组的N个元素。(-10^9 <= N[i] <= 10^9) 第N + 2行:1个数Q,Q为查询的数量。 第N + 3 至 N + Q + 2行:每行2个数,i,l(1 <= i <= N,i + l <= N)
共Q行,对应Q次查询的计算结果。
5 1 3 7 9 -1 4 1 2 2 2 3 2 1 5
4 10 16 19
解
前缀和算法:
#include <stdio.h> #include <malloc.h> int main() { int n; while (scanf_s("%d", &n) != EOF) { int *p = (int *)alloca(n * sizeof(int)),q; long long *pt = (long long *)alloca((n + 1) * sizeof(long long)); for (int i = 0; i < n; i++) { scanf_s("%d", p + i); pt[i + 1] = pt[i] + p[i]; } scanf_s("%d", &q); while (q--) { int i, l; scanf_s("%d%d", &i, &l); printf("%lld\n", pt[i+l-1] - pt[i-1]); } } }
总结一些关于内存分配的知识点。
常见内存分为三大区域
1.静态存储区(全局变量,static类型的局部变量等)
内存区域大,2个G左右,2^28个字节。
2.栈(局部变量等)
内存区域小,1~2M,2^20个字节。处理速度快。
3.堆(动态内存分配)
内存区域大,2个G左右,2^28个字节。
动态内存分配的相关函数:
void *malloc(unsigned int num_bytes);(分配的内存是位于堆中的,并且没有初始化内存的内容。)
void *calloc(unsigned n,unsigned size);(分配的内存是位于堆中的,并且初始化内存的内容。)
void *realloc(void *mem_address, unsigned int newsize);(先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。)
void *alloca(_In_ size_t _Size) (分配的内存是位于栈中的,并且初始化内存的内容,作用域结束时会自动释放内存。)
void free(void* p);(释放动态分配的内存。未被释放的空间再次被无法使用。)
原文:https://www.cnblogs.com/Ekalos-blog/p/9683914.html