对于线段树,我们一般需要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 = ;
} void add(int_t val) {
this->value += (end - begin + ) * 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 = ;
}
} int_t query (int begin,int end){
if(end < this->begin || begin > this->end) return ;
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[*sizeof(Node)];
int used = ; void* allocate() { return (++used) * sizeof(Node) + buf;} const int MaxN = ;
Node* tree;
int_t a[MaxN];
int n,m; Node* build(int begin,int end){
int mid = (begin + end)/; Node* node = new(allocate()) Node(begin,end);
if(begin != end){
node->left = build(begin ,mid);
node->right = build(mid+,end); } else if(begin == end){
node->value = a[begin];
} node->maintain();
return node;
} int main(){
scanf("%d%d",&n,&m); for(int i = ; i <= n; i++){
scanf("%lld",&a[i]);
} tree = build(,n); for(int i = ; i <= m; i++){
int opt,x,y;
int_t k;
scanf("%d",&opt);
if(opt == ){
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 ;
}

Code

接着这个代码说一下指针:

声明指针的方法是 type *x;

例如 int* a;

这样就是声明了一个int类型的指针,没有指向任何的内存。

然后,可以使用 int* a = NULL; 来初始化它,这时候它是一个空指针,一旦对它试图对它操作就会RE,比如 int* a = NULL;

指针本质上一个存贮8比特地址的整形变量,所以应该使用取地址符&来给指针赋值:

int c;

int *a = &c;

我们要通过指针给原本元素赋值:

int c = 0;

int *a = &c;

*a = 5;

这时输出c的值为5

另一种写法是引用,相当于给了某个变量另一个名字,本质仍然是存储地址。

int c = 0;

int &a = c;

a = 5;

与上面的写法是一样的效果。

指针不一定要指向某个变量,可以直接指向某个内存空间。

例如,我声明了一个结构体 struct custom{int a,b;};

然后,我们就可以使用指针指向内存中一个custom类型的内存,例如 custom* cs = new custom;

通过new关键字为这个指针创建一块内存,这个指针就指向它。

但是,如果想访问这个结构体的成员,则不同于原来的 "."访问,需要用 "->"来访问成员。

例如, cs->a = 0; 这样就算是给这个指针指向的结构体内存的a成员赋值为0。

但是,new是系统自动为其分配内存,比较慢,所以我们就可以创建一块内存池: char buf[400010*sizeof(custom)];

然后,用一个变量记录已经使用了内存池中的多少内存:int used = 0;

定义向这个内存池分配内存的函数:void* allocate() { return (++used) * sizeof(custom) + buf;}

used每次加1,记录已经使用了used个大小为sizeof(custom)的内存,然后加号后面是创建的内存池。

于是就可以使用这个内存池来分配内存:

custom *cs;

cs = new(allocate()) custom;

类型后面可以跟上构造函数,假设我们的custom有这样的构造函数:

custom(int a,int b){this->a = a;this->b = b;}

于是分配内存时就可以这样写:cs = new(allocate()) custom(1,2);

【OI】指针线段树&指针的更多相关文章

  1. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

  2. BZOJ 4695 最假女选手 线段树

    题意: 给定一个长度为 N序列,编号从1 到 N.要求支持下面几种操作: 1.给一个区间[L,R] 加上一个数x  2.把一个区间[L,R] 里小于x 的数变成x  3.把一个区间[L,R] 里大于x ...

  3. P2801 教主的魔法 (线段树)

    题目 P2801 教主的魔法 解析 成天做水题 线段树,第一问区间加很简单 第二问可以维护一个区间最大值和一个区间最小值,若C小于等于区间最小值,就加上区间长度,若C大于区间最大值,就加0 ps:求教 ...

  4. 指针-动态开点&合并线段树

    一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...

  5. CF547E Milk and Friends(AC自动机的fail指针上建主席树 或 广义后缀自动机的parent线段树合并)

    What-The-Fatherland is a strange country! All phone numbers there are strings consisting of lowercas ...

  6. 主席树-指针实现-找第k小数

    主席树,其实就是N颗线段树 只是他们公用了一部分节点(๑•̀ㅂ•́)و✧ 我大部分的代码是从一位大佬的那里看到的 我这个垃圾程序连Poj2104上的数据都过不了TLE so希望神犇能给我看看, 顺便给 ...

  7. 【线段树哈希】「Balkan OI 2016」Haker

    1A海星 题目大意 给你一个长度为 $n$ ,由小写字母构成的字符串 $S$ 和 $Q$ 个操作,每个操作是以下 3 种之一: 1 x y k :询问当前字符串从位置 $x$ 到 $y$ 的子串与从位 ...

  8. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  9. 【线段树】bzoj1756 Vijos1083 小白逛公园

    我们知道,求一段序列的最大子段和是O(n)的,但是这样是显然会超时的. 我们需要一个数据结构来支持修改和计算的操作,对于这种修改一个而查询区间的问题,考虑使用线段树. 在线段树中,除了左端点,右端点, ...

随机推荐

  1. Spring Data Redis入门示例:Hash操作(七)

    将对象存为Redis中的hash类型,可以有两种方式,将每个对象实例作为一个hash进行存储,则实例的每个属性作为hash的field:同种类型的对象实例存储为一个hash,每个实例分配一个field ...

  2. js文字内容部分选中的代码封装

    var textSelect = function(o, a, b){ //o是当前对象,例如文本域对象 //a是起始位置,b是终点位置 var a = parseInt(a, 10), b = pa ...

  3. 简述站点访问控制、基于用户的访问控制、httpd虚拟主机、持久链接等应用配置实例

    1 站点访问控制 可基于两种机制指明对哪些资源进行何种访问控制: 文件系统路径 URL路径 注意: 从上到下匹配,匹配到一个就立即执行 如果没有子目录的访问控制,但是有父目录的访问控制,则子目录继承父 ...

  4. PHP:Mysql 基础类

    文章来源:http://www.cnblogs.com/hello-tl/p/7592547.html <?php /** * __construct($Mysql_config) 构造函数 $ ...

  5. 【05】AJAX实例-检测用户名是否存在(实例)

    AJAX实例-检测用户名是否存在   用户注册时,需要填写个人信息,其中包括用户名.当用户输入完成时,JavaScript 需要及时检测用户名是否存在,如果存在给出提示,请用户更换用户名. 当然,这个 ...

  6. STM32F407 新建基于固件库的项目模板

    1.新建文件夹如图: 2.新建项目在USER文件夹中,选cpu如图: 若再弹出窗口, 直接点cancel 3.删了这俩文件夹: 4.复制文件到fwlib: src 存放的是固件库的.c 文件, inc ...

  7. 括号序列(Poj1141)

    Poj1141 题目描述: 定义合法的括号序列如下: 1 空序列是一个合法的序列 2 如果S是合法的序列,则(S)和[S]也是合法的序列 3 如果A和B是合法的序列,则AB也是合法的序列 例如:下面的 ...

  8. 主席树初探--BZOJ2588: Spoj 10628. Count on a tree

    n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线. 主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的 ...

  9. hdu - 1072 Nightmare(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1072 遇到Bomb-Reset-Equipment的时候除了时间恢复之外,必须把这个点做标记不能再走,不然可能造 ...

  10. JavaScript面向对象实现

    JavaScript面向对象实现 一:面向对象三大特征 继承,封装,多态! 二:JavaScript自定义对象  创建对象的方式: 方式1,对象初始化器方式: <script type=&quo ...