主席树

POJ 2104 主席树模板题

本小妞迷上赌 提交于 2019-11-28 19:18:05
#include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010; using namespace std; int a[maxn], b[maxn]; //第几个版本的根节点编号 int root[maxn << 5]; int lc[maxn << 5], rc[maxn << 5], sum[maxn << 5]; int sz;//节点个数 int n, m; int true_n; void build(int &rt, int l, int r) { rt = ++sz; if (l == r) return; int mid = (l + r) >> 1; build(lc[rt], l, mid); build(rc[rt], mid + 1, r); } int update(int id, int l, int r, int pos) { int _id = ++sz; lc[_id] = lc[id], rc[_id] = rc[id], sum[_id] = sum[id] + 1; if (l == r) return _id; int mid = (r + l) >> 1; if (pos <= mid) lc[_id] = update(lc[id],

主席树学习

ぃ、小莉子 提交于 2019-11-28 18:43:20
求区间第k小 题目链接: https://www.luogu.org/problem/P3834 #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define met(a, x) memset(a,x,sizeof(a)) #define inf 0x3f3f3f3f #define Rint register int using namespace std; const ll mod = 1e9 + 7; const int N = 2e5 + 10; const int M = 3e6 + 10; int a[N], b[N], c[N], cnt; int sum[N << 5], L[N << 5], R[N << 5]; inline int build(int l, int r) { int rt = ++cnt; sum[rt] = 0; if (l < r) { int mid = (l + r) / 2; L[rt] = build(l, mid); R[rt] = build(mid + 1, r); } return rt; } inline int update(int pre, int l, int r, int x) { int rt = ++cnt

EC Round 41 (Rated for Div. 2)主席树 E. Tufurama

寵の児 提交于 2019-11-28 18:42:37
简单分析一下,对于x<y,求a[x]>=y 同时a[y]>=x 再简化一下,求1-a[y]区间内大于>=y的个数。。。主席树牛逼 #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #define LL long long using namespace std; const int maxx = 2e5+6; struct node{ int l,r; int cnt; }tree[maxx*40]; int a[maxx]; int b[maxx]; int root[maxx]; int cnt; vector<int>v; int getval(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } void inserts(int l,int r,int pre,int &now,int pos){ now=++cnt; tree[now]=tree[pre]; tree[now].cnt++; if(l==r){ return ; } int mid=(l+r)>>1; if (pos<=mid){ inserts(l,mid,tree[pre].l,tree[now]

BZOJ2588: Count on a tree 主席树

血红的双手。 提交于 2019-11-28 17:59:56
题意 强制在线的树链上第K小 解题思路 树链上第k大问题很容易能想到树链剖分和主席树。如果我们对树深度优先遍历一遍,每遍历到一个结点u就在它父亲结点的基础上更新,那么T[u]这一棵树就维护了从u到根节点这一条链上的信息,再结合树的性质,从u到v这一条链上的信息就可以由u,v,lca(u,v),fa[lca(u,v)]计算得出。查询操作和区间第K小相类似。 AC代码 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; int n,m; int w[maxn],t[maxn],vnum; int T[maxn<<5],L[maxn<<5],R[maxn<<5],sum[maxn<<5],tnum; int build(int l,int r){ int rt=++tnum; sum[rt]=0; if(l<r){ int mid=(l+r)/2; L[rt]=build(l,mid); R[rt]=build(mid+1,r); } return rt; } int update(int rt,int l,int r,int x){ int nrt=++tnum; L[nrt]=L[rt];R[nrt]=R[rt];sum[nrt]=sum[rt]+1; if

静态主席树

て烟熏妆下的殇ゞ 提交于 2019-11-28 16:32:34
建树: #include <bits/stdc++.h> using namespace std; const int N=1e5+7; int n,m,sz; int root[N]/*存放根节点对应的三数组下标*/,ls[N*44]/*存放当前节点所对应的左节点三数组下标*/,rs[N*44]/*同ls*/,sum[N*44];//存放当前区间内数字的个数 //sum,rl,rs 可以整合为一个结构体 inline void update(int l,int r,int x,int &y,int v)//建树 { y=++sz;//y作为新节点下标返回给上一个节点的ls[y]/rs[y]做到更新上一节点的下标对应 sum[y]=sum[x]+1;//按照上一个结点更新新节点的sum值 if(l==r)return ; ls[y]=ls[x];rs[y]=rs[x]; //复制上一颗树的左右两节点所对应的三个数组下标同一节点的三个下标是一致的也就达到了连接节点的目的,因为rl和rs存在即可以共用之前的节点; int mid=(l+r)>>1; if(v<=mid)update(l,mid,ls[x],ls[y],v); else update(mid+1,r,rs[x],rs[y],v); }int main() { int t; scanf("%d",&t); while(t-

P4137 Rmq Problem / mex(主席树)

别来无恙 提交于 2019-11-28 16:25:17
传送门 思路: 直接上主席树,对于每个询问 \((l,r)\) ,我们在第 \(r\) 个版本的主席树中查询最晚出现的小于 \(l\) 最小的数就行了。 #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 200005; int n, m; int a[N], b[N << 1]; int D; void Hash() { sort(b + 1, b + D + 1); D = unique(b + 1, b + D + 1) - b - 1; for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + D + 1, a[i]) - b; } int rt[N * 22], ls[N * 22], rs[N * 22], minv[N * 22], tot; void build(int &o, int l, int r) { o = ++tot; minv[o] = 0; if(l == r) return; int mid = (l + r) >> 1; build(ls[o], l, mid); build(rs[o], mid + 1, r); } void

Home_W的难题4(主席树)

旧城冷巷雨未停 提交于 2019-11-28 11:10:28
Home_W的难题4 TimeLimit:1000MS MemoryLimit:128MB 64-bit integer IO format: %lld 已解决 | 已收藏(备注:树状数组或主席树) | 已有3人收藏了本题 Problem Description 给一个数列a1,a2,……an 查询在[l,r]区间内,大于等于x的数有多少个 Input 单组数据 第一个是两个整数n,q的代表数字的个数和查询的个数 接下来一行有n个数,a1,a2,……an 在接下来q行,每行有三个整数l,r,x; n,q<=1e5 0<=ai,x<=1e5 1<=l<=r<=n Output 对于每个查询输出相应的结果 SampleInput 10 10 5 1 3 10 5 3 2 9 0 9 5 7 1 1 6 1 1 10 6 2 6 8 1 5 3 6 10 8 1 3 5 2 5 7 4 8 8 5 9 0 SampleOutput 3 6 3 1 4 2 1 1 2 5 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 const int maxn=1e5+5; 8 int n

[NOI2010]超级钢琴 主席树

只愿长相守 提交于 2019-11-28 11:02:45
[NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样。 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #define ll long long using namespace std; const int _=5e5+7,INF=0x3f3f3f3f; int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f; } int n,k,l,r,sum[_],rt[_]; namespace seg { struct node {int l,r,siz;}e[_*20]; int cnt; void insert(int l,int r,int k,int x,int &y) { e[y=++cnt]=e[x]; e[y].siz++; if(l==r) return; int mid=(l+r)>>1; if(k<=mid) insert(l,mid,k,e[x].l,e[y].l); else insert(mid+1,r,k,e[x].r,e[y].r); } int

主席树(区间第k小的数)

谁说胖子不能爱 提交于 2019-11-28 10:01:43
题目链接: https://www.luogu.org/problem/P3834 首先要离散化,然后主席树模板。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mid (l+r)/2 5 using namespace std; 6 7 const int N = 200010; 8 int n, q, m, cnt = 0; 9 int a[N], b[N], T[N]; 10 int sum[N<<5], L[N<<5], R[N<<5]; 11 12 inline int build(int l, int r) 13 { 14 int rt = ++ cnt; 15 sum[rt] = 0; 16 if (l < r){ 17 L[rt] = build(l, mid); 18 R[rt] = build(mid+1, r); 19 } 20 return rt; 21 } 22 23 inline int update(int pre, int l, int r, int x) 24 { 25 int rt = ++ cnt; 26 L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = sum[pre]+1; 27 if (l < r){ 28

【主席树】HDU 6621 K-th Closest Distance

情到浓时终转凉″ 提交于 2019-11-27 18:07:43
在线区间查询,可以想到主席树 至于求第k小距离,可以二分 1 #include <bits/stdc++.h> 2 #define For(i,a,b) for(int i=a;i<=b;++i) 3 #define Dec(i,b,a) for(int i=b;i>=a;--i) 4 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin); 5 #define IO ios::sync_with_stdio(0),cin.tie(0) 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 typedef long long ll; 9 10 #define mid (l+r>>1) 11 const int N = 1000000; 12 int s[N*40],lc[N*40],rc[N*40],rt[100010],a[100010]; 13 int n,m,kase,ct; 14 void clr(int &x,int l,int r) 15 { 16 s[x=++ct]=0; 17 if(l==r) return; 18 clr(lc[x],l,mid); clr(rc[x],mid+1,r); 19 } 20 void upd(int x,int &y