对于线段树,我们一般需要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. popToViewController

    看到群里有人问popToViewController的用法 就写了下了 希望能帮到有需要的人 [self.navigationController popToViewController:[self. ...

  2. BZOJ 3144 切糕 最小割

    题意: 一个矩阵,每个格子分配一个数,不同的数字,代价不同,要求相邻格子数字差小等于d 求最小代价. 分析: 我猜肯定有人看题目就想到最小割了,然后一看题面理科否决了自己的这个想法…… 没错,就是最小 ...

  3. 树莓派 - 通过sysfs操控GPIO

    点亮或熄灭LED 硬件上,一个LED灯接在pi的Pin-25.  该引脚为BCM的GPIO26 $ gpio readall +-----+-----+---------+------+---+--- ...

  4. 新进Linux菜鸟,请多多关照

    早早知晓Linux的大名,一直未研究学习,近来看了kernel一些源代码,在网上搜过很多基础的知识.感觉这个Linux的世界很广大,值得好好深入学习.初生婴儿,呱呱落地,必先躺若干日后能坐,在学爬,进 ...

  5. admin源码之url设计

    如何实现批量设计url? 1.创建Django项目 2.新建app01 和 app02 3.在models.py中创建模型 4.在settings.py中完成数据库配置.app配置等 5.数据库迁移 ...

  6. Ubuntu中Hadoop环境搭建

    Ubuntu中Hadoop环境搭建 JDK安装 方法一:通过命令行直接安装(不建议) 有两种java可以安装oracle-java8-installer以及openjdk (1)安装oracle-ja ...

  7. 九度oj 题目1055:数组逆置

    题目1055:数组逆置 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:8225 解决:3932 题目描述: 输入一个字符串,长度小于等于200,然后将数组逆置输出. 输入: 测试数据有多组 ...

  8. 总结:常用的Linux系统监控命令(2)

    判断I/O瓶颈 mpstat命令 命令:mpstat -P ALL 1 1000 结果显示: 注意一下这里面的%iowait列,CPU等待I/O操作所花费的时间.这个值持续很高通常可能是I/O瓶颈所导 ...

  9. Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)

    C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell ...

  10. Redis集群方案之主从复制(待实践)

    Redis有主从复制的功能,一台主可以有多台从,从还可以有多台从,但是从只能有一个主.并且在从写入的数据不会复制到主. 配置 在Redis中,要实现主从复制架构非常简单,只需要在从数据库的配置文件中加 ...