指针版线段树

只是作一下,以后必须得写数组版的。。。???(然而很好写?

哦对,唯一的好处就是内存少一点,没了。(coding量似乎并不会少很多?也不会多很多?雾)

还有很重要的一点就是慢。。。(尽管虽然没有慢多少?该卡还是卡?)

哎呀真是好纠结。。。

问了些神犇,似乎大家并不知道线段树还能用数组写。。。

呵呵。。。

然后看了一眼内存,指针严格开2n-1就好,而数组其实是要开4n的。。。。

COJ上的数据太水了,数据只有大概。。。

所以呢。。。。。要不我先用指针写几次再说?

不过是真心写着舒服。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(‘ ‘)
  8 #define ENT putchar(‘\n‘)
  9 #define CH for(int d=0;d<=1;d++) if(ch[d])
 10 using namespace std;
 11 const int maxn=1000000+10,maxnode=1080000+10,inf=-1u>>1;
 12 struct node{
 13     node*ch[2];int mi,mx,sm;
 14     void sett(int tag){mi=mx=sm=tag;return;}
 15     void update(){
 16         mi=inf;mx=-inf;sm=0;
 17         CH{mi=min(mi,ch[d]->mi);mx=max(mx,ch[d]->mx);sm+=ch[d]->sm;}
 18         return;
 19     }
 20 }seg[maxnode],*root,*nodecnt=seg;
 21 int A[maxn],n,Q;
 22 void build(node*&x,int L,int R){
 23     x=nodecnt++;
 24     if(L==R) x->sett(A[L]);
 25     else{
 26         int M=L+R>>1;
 27         build(x->ch[0],L,M);
 28         build(x->ch[1],M+1,R);
 29         x->update();
 30     } return;
 31 }
 32 int _mi,_mx,_sm,pos,cv,ql,qr;
 33 void query(node*x,int L,int R){
 34     if(ql<=L&&R<=qr){
 35         _mi=min(_mi,x->mi);
 36         _mx=max(_mx,x->mx);
 37         _sm+=x->sm;
 38     }
 39     else{
 40         int M=L+R>>1;
 41         if(ql<=M) query(x->ch[0],L,M);
 42         if(qr>M) query(x->ch[1],M+1,R);
 43     }
 44 }
 45 void update(node*&x,int L,int R){
 46     if(L==R) x->sett(cv);
 47     else{
 48         int M=L+R>>1;
 49         if(pos<=M) update(x->ch[0],L,M);
 50         else update(x->ch[1],M+1,R);
 51         x->update();
 52     }
 53 }
 54 inline int read(){
 55     int x=0,sig=1;char ch=getchar();
 56     while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
 57     while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
 58     return x*=sig;
 59 }
 60 inline void write(int x){
 61     if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
 62     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 63     for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
 64 }
 65 inline char readc(){
 66     char x=getchar();
 67     while(!isalpha(x)) x=getchar();
 68     return x;
 69 }
 70 void init(){
 71     n=read();
 72     for(int i=1;i<=n;i++) A[i]=read();
 73     build(root,1,n);
 74     return;
 75 }
 76 void work(){
 77     Q=read();char tp;
 78     while(Q--){
 79         tp=readc();ql=read();qr=read();
 80         if(tp==‘Q‘){
 81             _sm=0;_mx=-inf;_mi=inf;
 82             query(root,1,n);
 83             putchar(‘M‘);
 84             putchar(‘a‘);
 85             putchar(‘x‘);
 86             putchar(‘N‘);
 87             putchar(‘u‘);
 88             putchar(‘m‘);
 89             putchar(‘:‘);
 90             putchar(‘ ‘);
 91             write(_mx);
 92             putchar(‘,‘);
 93             putchar(‘ ‘);
 94             putchar(‘M‘);
 95             putchar(‘i‘);
 96             putchar(‘n‘);
 97             putchar(‘N‘);
 98             putchar(‘u‘);
 99             putchar(‘m‘);
100             putchar(‘:‘);
101             putchar(‘ ‘);
102             write(_mi);
103             putchar(‘,‘);
104             putchar(‘ ‘);
105             putchar(‘S‘);
106             putchar(‘u‘);
107             putchar(‘m‘);
108             putchar(‘:‘);
109             putchar(‘ ‘);
110             write(_sm);
111             ENT;
112         }
113         else{
114             pos=ql;cv=qr;
115             update(root,1,n);
116         }
117     }
118     return;
119 }
120 void print(){
121     return;
122 }
123 int main(){init();work();print();return 0;}
时间: 2024-11-05 00:44:33

指针版线段树的相关文章

扫描线讲解,动态开点版线段树

扫描线 首先,扫描线是干什么的?扫描线一般运用在图形上面,它和它的字面意思十分相似,就是一条线在整个图上扫来扫去,它一般被用来解决图形面积,周长等问题,以一道例题为例.给出n个正方形,这些正方形在平面直角坐标系中互相重叠摆放,但四条边都与坐标轴平行,例如下图所示.那么知道题目了,怎么运用呢?首先我们需要知道怎么用暴力解决这个问题,根据图片可知图中的面积是SABCD+SHEFG-SIDJE暴力搜索是个好东西,但是当数据范围大了怎么办?这里就要讲到扫描线. 扫描线对于这道例题可以抽象为这四条紫色的直

COJ 1010 WZJ的数据结构(十) 线段树区间操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,高效执行以下过程: #include<iostream>using namespace std;const int maxn=100010;int A[maxn];int tp,ql,qr,v;int

BZOJ3110 ZJOI2013 K大数查询 线段树套线段树

题意:给定一个数列,维护:1.在a和b之间插入c  2.询问[a,b]中的第c大 题解: 权值线段树套区间线段树 外层的权值线段树中每个节点如果维护[L,R]这个区间,那么该节点所对应的线段树维护的就是[L,R]这些数在每个区间里出现了几次,也就是说如果外层线段树的某个节点维护[L,R],其所对应的内层线段树中某个节点[l,r]维护的值就是[L,R]这些数在[l,r]这个区间中出现的次数. 最后吐槽一下动态内存+指针版线段树MLE……尼玛我写指针版完全习惯了根本就不会写数组版了QAQ,自己拿数据

BZOJ3295 CQOI2011 动态逆序对 树状数组套线段树

离线倒着做,每次加入一个节点后新增的逆序对数量就是其左边大于它的数的个数(左边数的总数-左边小于它的数的个数)+右边小于它的数的个数 用树状数组维护求和,对于树状数组中每个节点v所对应的区间线段树维护区间[l,r]中大于v的数的个数. 最后唯一的问题就是指针版线段树MLE-- #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <alg

SegmentTree-Complete 线段树完全版

线段树完全版关键词:延迟加载.懒标记Lazy Tag 单点更新的情况比较简单.请看 线段树基础版 下面说说区间更新的情况. 场景是这样的,还是刚刚的数,求区间的和. #define lson rt<<1 #define rson rt<<1|1 #define len (r-l+1) //(l,r)区间的长度 这次是区间更新,我们要用到区间的长度 建树 build和pushUp不变.我们把树建立好打印一下: [1]:36 [2]:26 [3]:10 [4]:15 [5]:11 [6

线段树学习

此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求和 介绍Lazy思想:lazy-tag思想,记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率. 在此通俗的解释我理解的Lazy意思,比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果

【hihoCoder】第20周 线段树

题目: 输入 每个测试点(输入文件)有且仅有一组测试数据. 每组测试数据的第1行为一个整数N,意义如前文所述. 每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品的重量Pi. 每组测试数据的第3行为一个整数Q,表示小Hi进行的操作数. 每组测试数据的第N+4~N+Q+3行,每行分别描述一次操作,每行的开头均为一个属于0或1的数字,分别表示该行描述一个询问和一次商品的价格的更改两种情况.对于第N+i+3行,如果该行描述一个询问,则接下来为两个整数Li, Ri,

线段树详解及模板 (转载)

一步一步理解线段树 目录 一.概述 二.从一个例子理解线段树 创建线段树 线段树区间查询 单节点更新 区间更新 三.线段树实战 -------------------------- 一 概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(logn). 线段树的每个节点表示一个区间,子节点则分别表示父节点的左右半区间,例如父亲的区间是[a,b],那么(c=(a+b)

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放