对于线段树,我们一般需要n*4的空间去存储线段树,然后有一种玄学操作是用指针来实现线段树。
#include <inttypes.h> #include <algorithm> #include <cstdio> #include <iostream> #include <vector> #define debug(x) std::cout<< #x << " = " << std::endl; typedef long long int int_t; using std::cin; using std::cout; using std::endl; struct Node{ Node *left,*right; int_t value; int begin,end; int mark; Node(int begin, int end) { this->begin = begin; this->end = end; left = right = NULL; mark = 0; } void add(int_t val) { this->value += (end - begin + 1) * val; mark += val; } void maintain() { if(begin != end) { this->value = left -> value + right->value; } } void pushDown(){ if (mark) { if(begin!= end) { left -> add(mark); right -> add(mark); } mark = 0; } } int_t query (int begin,int end){ if(end < this->begin || begin > this->end) return 0; if(this->begin >= begin && this->end <= end) return this->value; this->pushDown(); return left->query(begin,end) + right->query(begin, end) ; } void add(int begin,int end,int_t val){ if(end < this->begin || begin > this->end) return; if(this->begin >= begin && this->end <= end) { this->add(val); return ; } this->pushDown(); left->add(begin,end,val); right->add(begin,end,val); this->maintain(); } }; char buf[400010*sizeof(Node)]; int used = 0; void* allocate() { return (++used) * sizeof(Node) + buf;} const int MaxN = 200010; Node* tree; int_t a[MaxN]; int n,m; Node* build(int begin,int end){ int mid = (begin + end)/2; Node* node = new(allocate()) Node(begin,end); if(begin != end){ node->left = build(begin ,mid); node->right = build(mid+1,end); } else if(begin == end){ node->value = a[begin]; } node->maintain(); return node; } int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++){ scanf("%lld",&a[i]); } tree = build(1,n); for(int i = 1; i <= m; i++){ int opt,x,y; int_t k; scanf("%d",&opt); if(opt == 1){ scanf("%d%d%lld",&x,&y,&k); tree->add(x,y,k); } else { scanf("%d%d",&x,&y); printf("%lld\n",tree->query(x,y)); } } return 0; }