【模板】动态主席树

如题,这是一个模板。。。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cctype>
  6
  7 inline void read(int & x)
  8 {
  9     x = 0;
 10     int k = 1;
 11     char c = getchar();
 12     while (!isdigit(c))
 13         if (c == ‘-‘) c = getchar(), k = -1;
 14         else c = getchar();
 15     while (isdigit(c))
 16         x = (x << 1) + (x << 3) + (c ^ 48),
 17         c = getchar();
 18     x *= k;
 19 }
 20
 21 struct Node
 22 {
 23     int l, r, k, q;
 24 }q[101010];
 25
 26 const int MAXN = 1010100 << 6;
 27 int n, m, tot = 0, id = 0;
 28 int a[MAXN], b[MAXN], ls[MAXN], rs[MAXN], sum[MAXN];
 29 int T[MAXN], S[MAXN], use[MAXN];
 30
 31 char opt[11];
 32
 33 inline int lowbit(int x)
 34 {
 35     return x & (-x);
 36 }
 37
 38 inline int Lsh(int x)
 39 {
 40     return std::lower_bound(a + 1, a + tot + 1, x) - a;
 41 }
 42
 43 inline void Pushup(int u)
 44 {
 45     sum[u] = sum[ls[u]] + sum[rs[u]];
 46 }
 47
 48 int Build(int l, int r)
 49 {
 50     int rt = ++id;
 51     sum[rt] = 0;
 52     if (l != r)
 53     {
 54         int mid = l + r >> 1;
 55         ls[rt] = Build(l, mid);
 56         rs[rt] = Build(mid + 1, r);
 57     }
 58     return rt;
 59 }
 60
 61 int Add(int pre, int l, int r, int x, int cm)
 62 {
 63     int rt = ++id;
 64     ls[rt] = ls[pre],
 65     rs[rt] = rs[pre],
 66     sum[rt] = sum[pre] + cm;
 67     if (l < r)
 68     {
 69         int mid = l + r >> 1;
 70         if (x <= mid)
 71             ls[rt] = Add(ls[pre], l, mid, x, cm);
 72         else
 73             rs[rt] = Add(rs[pre], mid + 1, r, x, cm);
 74     }
 75     return rt;
 76 }
 77
 78 inline void Modify(int u, int pos, int x)
 79 {
 80     while (u <= n)
 81     {
 82         S[u] = Add(S[u], 1, tot, pos, x);
 83         u += lowbit(u);
 84     }
 85 }
 86
 87 inline int Sum(int u)
 88 {
 89     int ans = 0;
 90     while (u > 0)
 91     {
 92         ans += sum[ls[use[u]]];
 93         u -= lowbit(u);
 94     }
 95     return ans;
 96 }
 97
 98 int Query(int u, int v, int ur, int vr, int l, int r, int k)
 99 {
100     if (l >= r) return l;
101     int mid = l + r >> 1;
102     int df = Sum(v) - Sum(u) + sum[ls[vr]] - sum[ls[ur]];
103     if (k <= df)
104     {
105         for (int i = u; i; i -= lowbit(i))
106             use[i] = ls[use[i]];
107         for (int i = v; i; i -= lowbit(i))
108             use[i] = ls[use[i]];
109         return
110             Query(u, v, ls[ur], ls[vr], l, mid, k);
111     }
112     else
113     {
114         for (int i = u; i; i -= lowbit(i))
115             use[i] = rs[use[i]];
116         for (int i = v; i; i -= lowbit(i))
117             use[i] = rs[use[i]];
118         return
119             Query(u, v, rs[ur], rs[vr], mid + 1, r, k - df);
120     }
121 }
122
123 signed main()
124 {
125     read(n), read(m);
126     for (int i = 1; i <= n; ++i)
127         read(b[i]), a[++tot] = b[i];
128     for (int i = 1; i <= m; ++i)
129     {
130         scanf("%s", opt);
131         if (opt[0] == ‘Q‘)
132             read(q[i].l), read(q[i].r), read(q[i].k), q[i].q = 1;
133         else
134             read(q[i].l), read(q[i].r), q[i].q = 0,
135             a[++tot] = q[i].r;
136     }
137     std::sort(a + 1, a + tot + 1);
138     int cur = std::unique(a + 1, a + tot + 1) - a - 1;
139     tot = cur;
140     T[0] = Build(1, tot);
141     for (int i = 1; i <= n; ++i)
142         T[i] = Add(T[i - 1], 1, tot, Lsh(b[i]), 1);
143     for (int i = 1; i <= n; ++i)
144         S[i] = T[0];
145     for (int i = 1; i <= m; ++i)
146         if (q[i].q)
147         {
148             for (int j = q[i].l - 1; j; j -= lowbit(j))
149                 use[j] = S[j];
150             for (int j = q[i].r; j; j -= lowbit(j))
151                 use[j] = S[j];
152             printf("%d\n", a[Query(q[i].l - 1, q[i].r, T[q[i].l - 1], T[q[i].r], 1, tot, q[i].k)]);
153         }
154         else
155         {
156             Modify(q[i].l, Lsh(b[q[i].l]), -1);
157             Modify(q[i].l, Lsh(q[i].r), 1);
158             b[q[i].l] = q[i].r;
159         }
160     return 0;
161 }

原文地址:https://www.cnblogs.com/yanyiming10243247/p/10057783.html

时间: 2024-11-05 04:37:29

【模板】动态主席树的相关文章

[Luogu 3701] 「伪模板」主席树

[Luogu 3701] 「伪模板」主席树 <题目链接> 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 byx 的树中的每一个人连有向边,手气君的树中的每一个人向 T 连有向边,边权为这个人的寿命.统计同一棵树中的膜法师数量 x.如果一个人是主席,那么边权要加上 x.(续得好啊) 然后,如果 byx 树中的一个点 i 能赢手气君树中的点 j,那么连 i->j,边权为 1. 跑最大

P3701 「伪模板」主席树

P3701 「伪模板」主席树 题目背景 byx和手气君都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 题目描述 很快,这棵树就开花结果了.byx和手气君惊讶的发现,这是一棵主席树,树上长满了主席和主席的朋友们.这棵树上一共有五种人,主席(J),记者(HK),高人(W),女王(E)和膜法师(YYY).他们发现,他们的主席树上的人数相同,都为N. 研究发现,这五种人的输赢如上图所示(一样的人不能PK),箭头指向输的人.至于为

zoj 2112 Dynamic Rankings 带修改区间第K大 动态主席树

pass 首先,个人觉得把这个数据结构理解成树状数组套主席树是十分不严谨的.主席树的本质是可持久化权值线段树与前缀和思想的结合.而动态主席树是可持久化权值线段树与树状数组思想的结合.并非树套树般的泾渭分明的叠加. 其次,大概讲下对动态主席树的理解.我们静态主席树中,第i个版本维护的是[1,i]的权值线段树,我们利用前缀和的思想,通过y的版本-x的版本得到[x,y]的权值线段树,从而剥离出一颗对应区间的权值线段树.我们考虑在这个情况下,如果需要修改第a[i]的值,那么从i,i+1,i+2.....

【Luogu】P3384主席树模板(主席树查询K小数)

YEAH!我也是一个AC主席树模板的人了! 其实是个半吊子 我将尽量详细的讲出我的想法. 主席树太难,我们先搞普通线段树好了 普通线段树怎么做?我的想法是查询K次最小值,每次查完把查的数改成INF,查完再改回来... MDZZ 于是就有了主席树. 先不考虑主席树,我们来考虑一个奇特的线段树. 一般的线段树,数列位置是下标,而把数列维护值作为线段树中存的元素. 那我们如果反过来,把数列元素当做线段树的下标...??? 比如说数列[4 2 3 1] 如果线段树的下标是1.2.3.4......? 那

动态主席树 优化版

和大奕哥一起学习了主席树,机房里杰哥看了之后一直说可以优化空间,题解写的太low了,所以我今天写了一个动态开点的线段树来优化一波空间,bz上试了一下,确实比网上看的题解省空间. 网上的题解是每一次都新开点,是可持久化的写法,我写的是正经的线段树动态开点. 附上代码 #include<bits/stdc++.h> using namespace std; const int N=10010,INF=1e9+10; int n,m,pl,tl,mx; int a[N<<1],num[N

【模板】主席树

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

洛谷 3701「伪模板」主席树(最大流)

题目背景 byx和手气君都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 题目描述 很快,这棵树就开花结果了.byx和手气君惊讶的发现,这是一棵主席树,树上长满了主席和主席的朋友们.这棵树上一共有五种人,主席(J),记者(HK),高人(W),女王(E)和膜法师(YYY).他们发现,他们的主席树上的人数相同,都为N.   研究发现,这五种人的输赢如上图所示(一样的人不能PK),箭头指向输的人.至于为什么,留给同学们自己思考.

【模板】 主席树

1 // poj2104 2 // p3834 3 #include<iostream> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 const int N=1e5+7; 8 int a[N],b[N],rt[N]; 9 int cnt=0; 10 struct node{ 11 int l,r,sum; 12 }tr[N*20]; 13 void build(int& o,

P3834 【模板】主席树

题目地址 注意点: MAXN可开到1e7. #include<cstdio> #include<iostream> using namespace std; const int MAXN=1e7,INF=2e9; struct Node{ int ls,rs; int cnt; }tr[MAXN]; int nodeCnt=0; void insert(int p,int &q,int l,int r,int val){ if(!q)q=++nodeCnt; if(l==r