主席树几道题目

阅读: 评论:0

主席树几道题目

主席树几道题目


主要参考cxlove博客kuangbin博客

感觉主席树和划分树有类似之处,分治的思想


Poj2104 主席树静态区间第k值

以每个位置为起点,建立一棵主席树,保存后缀区间的情况。

每个节点保存的是该后缀在相应区间数的个数

const int MAXN = 100010;
const int MOD = 1000000;
int a[MAXN], t[MAXN];
int T[MAXN * 30], lson[MAXN * 30],rson[MAXN * 30], c[MAXN * 30];
int n, sz, q;
int tot;
void init_hash()
{FE(i, 1, n) t[i] = a[i];sort(t + 1, t + 1 + n);sz = unique(t + 1, t + 1 + n) - t - 1;
}
int build(int l, int r)
{int rt = tot++;c[rt] = 0;if (l != r){int m = (l + r) >> 1;lson[rt] = build(l, m);rson[rt] = build(m + 1, r);}return rt;
}int hash(int x)
{returnlower_bound(t + 1, t + 1 + n, x) - t;
}int update(int rt, int pos, int val)
{int new_rt = tot++;int tmp = new_rt;c[new_rt] = c[rt] + val;int l = 1, r = sz;while (l < r){int m = (l + r) >> 1;if (pos <= m){lson[new_rt] = tot++; rson[new_rt] = rson[rt];new_rt = lson[new_rt]; rt = lson[rt];r = m;}else{rson[new_rt] = tot++; lson[new_rt] = lson[rt];new_rt = rson[new_rt]; rt = rson[rt];l = m + 1;}c[new_rt] = c[rt] + val;}return tmp;
}int query(int L, int  R, int k)
{int l = 1, r = sz;while (l < r){int m = (l + r) >> 1;if (c[lson[L]] - c[lson[R]] >= k){L = lson[L]; R = lson[R];r = m;}else{k -= c[lson[L]] - c[lson[R]];///!!!L = rson[L]; R = rson[R];l = m + 1;}}return l;
}int main()
{int x, y, z;while (cin >> n >> q){tot = 0;FE(i, 1, n) RI(a[i]);init_hash();T[n + 1] = build(1, sz);///!!!FED(i, n, 1){int pos = hash(a[i]);T[i] = update(T[i + 1], pos, 1);}while (q--){RIII(x, y, z);printf("%dn", t[query(T[x], T[y + 1], z)]);}}
}


spoj EQUERY 静态区间,区间中不同值的数的个数

对于每一个起始位置,都建立一棵主席树

从后往前更新,更新的时候就是在next位置先减掉,然后更新在当前位置。

主席树又称为可持久化线段树,其本质上是保存了所有的历史信息。

也可以理解为多棵线段树,在更新的时候,充分共同利用历史信息

对于点更新来说,更新的总是某一棵子树,另外一棵子树,则指向原来的结点即可。

可是即使如此,主席树还是需要大量的空间。

const int MAXN = 100010;
const int MOD = 1000000;int a[MAXN], t[MAXN];
int T[MAXN * 60], lson[MAXN * 60],rson[MAXN * 60], c[MAXN * 60];
int n, q;
int tot;
map<int, int> mp;int build(int l, int r)
{int rt = tot++;c[rt] = 0;if (l != r){int m = (l + r) >> 1;lson[rt] = build(l, m);rson[rt] = build(m + 1, r);}return rt;
}int update(int rt, int pos, int val)
{int new_rt = tot++;int tmp = new_rt;c[new_rt] = c[rt] + val;int l = 1, r = n;while (l < r){int m = (l + r) >> 1;if (pos <= m){lson[new_rt] = tot++; rson[new_rt] = rson[rt];new_rt = lson[new_rt]; rt = lson[rt];r = m;}else{rson[new_rt] = tot++; lson[new_rt] = lson[rt];new_rt = rson[new_rt]; rt = rson[rt];l = m + 1;}c[new_rt] = c[rt] + val;}return tmp;
}int query(int rt, int pos)
{int ans = 0;int l = 1, r = n;while (l < r)///(pos < r){int m = (l + r) >> 1;if (pos <= m){rt = lson[rt];r = m;}else{ans += c[lson[rt]];rt = rson[rt];l = m + 1;}}return ans + c[rt];
}int main()
{int x, y, z;while (cin >> n){tot = 0;FE(i, 1, n) RI(a[i]);mp.clear();T[n + 1] = build(1, n);FED(i, n, 1){if (mp.find(a[i]) == mp.end()){T[i] = update(T[i + 1], i, 1);}else{int tmp = update(T[i + 1],mp[a[i]], -1);T[i] = update(tmp, i, 1);}mp[a[i]] = i;}cin >> q;while (q--){RII(x, y);printf("%dn", query(T[x], y));}}
}

zoj 2112 Dynamic Rankings 动态第k值,树状数组套线段树


、、、

本文发布于:2024-01-30 06:09:22,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170656616619783.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:几道   题目   主席
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23