主席树的另一种写法

代码

int hd[maxn];
struct Tree{ int lson,rson,cnt; };
struct CMTree
{
   int id;
   Tree tree[maxn*40];
   void init(){ id=0; }
   void pushup(int rt){ e.cnt=tree[e.lson].cnt+tree[e.rson].cnt; }
   void Build_tree(int& rt,int le,int ri)
   {
       rt=id++;
       e.cnt=0;
       if(le==ri) return;
       int mid=(le+ri)/2;
       Build_tree(e.lson,le,mid);
       Build_tree(e.rson,mid+1,ri);
       pushup(rt);
   }
   void Update(int pre,int& rt,int le,int ri,int k,int d)
   {
       rt=id++;
       if(le==ri){ e.cnt=p.cnt+d; return; }
       int mid=(le+ri)/2;
       if(k<=mid)
       {
           Update(p.lson,e.lson,le,mid,k,d);
           e.rson=p.rson;
       }
       else
       {
           Update(p.rson,e.rson,mid+1,ri,k,d);
           e.lson=p.lson;
       }
       pushup(rt);
   }
   int Query(int rt,int le,int ri,int x,int y)
   {
       if(x<=le&&ri<=y) return e.cnt;
       int mid=(le+ri)/2;
       int ret=0;
       if(x<=mid) ret+=Query(e.lson,le,mid,x,y);
       if(y>mid)  ret+=Query(e.rson,mid+1,ri,x,y);
       return ret;
   }

}CT;

时间: 2024-10-05 18:40:24

主席树的另一种写法的相关文章

【模板】主席树

主席树..高大上的名字..原名叫可持久化线段树..也有人叫函数式线段树(其实叫什么都不重要). 本来的作用就是字面意思..持久化的线段树,支持修改之后查找某次修改之前的版本.(在NOIP之前在算法导论上看到过,当时觉得没什么,现在才知道好厉害的数据结构) 具体来怎么实现呢..其实就是每次修改的时候都新开一个根节点然后把和修改有关的区间一路新建下去,与修改无关的区间就继承上次修改版本的节点,这样会节省空间. 来应用一下,一个基础的应用就是区间K小值查询(poj2104).即给定一个序列,给出L,R

[知识学习] 主席树

这两天学习了主席树,基本上搞懂了主席树是怎么操作的 主席树,是一种可持久化线段树.最简单的操作就是维护静态区间第 \(k\) 小 主席树通过维护历史版本,实现查询区间的有关操作 主席树的原理 假设现在有这么一个序列:\(4,1,3,5,2\) 问如何求出区间[1,3]内大小为第二的数? 利用大眼观察法,很显然是3 那么让计算机去怎么实现呢?它又没有眼睛 对于这个序列,我们可以先建一颗空的权值线段树,命名为"树0"(方便后面的使用),如图: 别告诉我你不知道什么是权值线段树,自己去百度:

Count on a tree SPOJ 主席树+LCA(树链剖分实现)(两种存图方式)

Count on a tree SPOJ 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)[GO!] 题意 是说有棵树,每个节点上都有一个值,然后让你求从一个节点到另一个节点的最短路上第k小的值是多少. 解题思路 看到这个题一想以为是树链剖分+主席树,后来写着写着发现不对,因为树链剖分我们分成了一小段一小段,这些小段不能合并起来求第k小,所以这个想法不对.奈何不会做,查了查题解,需要用LCA(最近公共祖先),然后根据主席树具有区间加减的性质,我们

主席树(一种可持久化线段树)

study from: 静态主席树:https://blog.csdn.net/a1351937368/article/details/78884526 动态主席树:https://blog.csdn.net/WilliamSun0122/article/details/77885781 静态: https://www.luogu.org/problemnew/show/P3834 1 #include <cstdio> 2 #include <cstdlib> 3 #includ

AcWing 255. 第K小数 (主席树写法)

区间k小数是主席树的模板题目,如果区间不包含,用莫队+权值线段树也能解 主席树是可持久化线段树,所为可持久化,就是每次只新增不一样的节点,而保留前面的版本,这样可以做到查询. 如果询问时1-r,那么直接主席树,询问的是l-r,就用到前缀和思想,具体看代码注释 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #inclu

POJ2104 K-th Number[主席树]

K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 51440   Accepted: 17594 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse

POJ_2104_Kth(主席树)

描述 http://poj.org/problem?id=2104 给出一个n个数的数列,m次询问,每次询问求区间[l,r]中第k小的数,无修改操作. 分析 静态的主席树裸题. 首先考虑把数据离散化,这样一共有n个数,分别为1,2,...,n-1,n(如果没有重复的话)(如果题目里面说有重复且重复数字排名相同,就去一下重就好了).用N=n的线段树来表示某一区间当前的情况,其中节点a[k]表示在这个区间内,属于[a[k].L,a[k].R]的数字共有多少.这样在这个区间上求第K小数的操作就类似于平

主席树POJ2104

求区间第k大数是多少 用我惯用的线段树写法似乎不适合写主席树,看别人的代码好半天才看懂 用root表示每一个前缀树的根,思想大致是由第i-1个树构成的树建第i个树,由于加入一个数只需要log级别修改,所以建树效率很高. 主席树的精髓在于可持续化,就是说之前区间的信息不去修改它,递推加入新元素的时候,要新开log个空间来存储.因为主席树本身比较占用空间,只需改变这些空间的指向就可以重复利用不变的空间,达到节省空间的目的. 简而言之,主席树是一种重复利用数据不变的空间,建成空间上只有一颗完整的树,但

【树状数组套主席树】带修改区间K大数

P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题.你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令. 对于每一个询问指令,你必须输出正确的回答. 输入输出格式输入格