对于线段树,我们一般需要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. pip install MySQL-python error "can't open config-win.h"

    http://blog.csdn.net/xxm524/article/details/48754139

  2. JAVA基础——对象流

    对象的输入输出流的作用: 用于写入对象 的信息和读取对象的信息. 使得对象持久化.    ObjectInputStream   : 对象输入流    ObjectOutPutStream  :对象输 ...

  3. vue-cli项目中使用mockjs(基础使用和全局配置使用)

    参考:vue+mockjs 模拟数据,实现前后端分离开发 (Github-Demo可查看全部代码),Mockjs ,Axios 很多时候前后端分离的项目在开发过程中前端所需数据和后端接口并不会同步开发 ...

  4. C++ 之 string

    C++ 的 string 类封装了很多对字符串的常用操作. string 类是模板类 basic_string类,以 char作为其元素类型的类. string 以单字节作为一个字符,如果处理多字符集 ...

  5. 启用Windows10的Linux子系统并安装图形界面

    前言 目前市面上的PC电脑主要运行着四大类系统,它们分别是微软的Windows.苹果的MacOS.Linux的发行版以及Unix类系统.其中Linux和Unix都是开源的,因此市面出现的众多基于Lin ...

  6. linux 批量修改文件名 文件名只保留部分,去掉部分

    问题:linux系统中文件名包含中文,导致页面访问不了文件.就是上条博客中的解决方法二遗留问题. 文件名中有以下格式:TC2_诺而达铜管(中山)有限公司.pdf ,要改为TC2.pdf,去掉中文部分 ...

  7. ruby on rails安装(win7x64)

    Ruby下载地址http://rubyinstaller.org/downloads/ (以安装2.1.7为例,2.2.3未能安装成功) 安装完之后测试是否安装成功

  8. configparser logging

    configparser模块 # 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值). import configpar ...

  9. noi.ac NOIP2018 全国热身赛 第二场 T1 ball

    [题解] 可以发现每次推的操作就是把序列中每个数变为下一个数,再打一个减一标记:而每次加球的操作就是把球的位置加上标记,再插入到合适的位置. 用set维护即可. #include<cstdio& ...

  10. Zoj 3781(构造)

    Zoj 3781(构造) Zoj 3781 As we all know, Coach Gao is a talented chef, because he is able to cook M dis ...