函数式线段树(区间数出现次数)
来源:互联网 发布:暴风tv安装软件 编辑:程序博客网 时间:2024/06/05 07:55
函数式线段树主要功能有区间 k 大值之类。
其核心思想为:在一个线段树上面利用原有的信息,每次只增加 log 级别的节点,就可以完成复制信息的任务。
这有什么用呢?假设你需要求区间 k 大值,你可以考虑对于每一个节点 i 建一颗线段树,所储存的为每个数在前 i 位上出现的次数,这样就可以在 log n 的时间内统计出一段数字在前 i 为上出现的次数。然后利用区间减法,就可以在 log n 时间内求出区间内数的出现次数前缀和为 k 的那一位,最后确定答案。
这是一道叫 lyp的题,其所求为区间内数的出现次数。代码是动态实现的:
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define swap(a, b, t) ({t _ = (a); (a) = (b); (b) = _;})#define max(a, b) ({int _ = (a), __ = (b); _ > __ ? _ : __;})#define min(a, b) ({int _ = (a), __ = (b); _ < __ ? _ : __;})#define maxv 2000005#define maxn 100005int n, m, tot, k, ll, rr, ans, R = 100000;int a[maxn];struct da{int s; da * l, * r;} ve[maxv], * root[maxn];void build(da * & p, int l, int r){p = ve + (++ tot);if (l < r) build(p->l, l, l + r >> 1), build(p->r, (l + r >> 1) + 1, r);}void revise(da * & p, da * q, int l, int r){p = ve + (++ tot), * (p) = * (q), ++ p->s;if (l == r) return;if (k <= l + r >> 1) revise(p->l, q->l, l, l + r >> 1);else revise(p->r, q->r, (l + r >> 1) + 1, r);}int query(da * p, da * q, int l, int r){if (ll <= l && r <= rr) return q->s - p->s;int ans = 0, m = l + r >> 1;if (ll <= m) ans += query(p->l, q->l, l, m);if (rr > m) ans += query(p->r, q->r, m + 1, r);return ans;}int main(){freopen("lyp.in", "r", stdin);freopen("lyp.out", "w", stdout);scanf("%d%d", & n, & m);build(root[0], 0, rr = R);for (int i = 1; i <= n; ++ i){scanf("%d", a + i);k = a[i], revise(root[i], root[i - 1], 0, R);ll = k + 1, ans += query(root[0], root[i], 0, R);}printf("%d\n", ans);for (int p, q, l; m --; ){scanf("%d%d", & p, & q);if (l = ans, a[p] < q){ll = a[p] + 1, rr = q, l -= query(root[0], root[p - 1], 0, R);ll = a[p], rr = q - 1, l += query(root[p], root[n], 0, R);}else if (q < a[p]){ll = q + 1, rr = a[p], l += query(root[0], root[p - 1], 0, R);ll = q, rr = a[p] - 1, l -= query(root[p], root[n], 0, R);}printf("%d\n", l);}return 0;}
- 函数式线段树(区间数出现次数)
- 【POJ 3368】【RMQ 或者 线段树】Frequent values【求出区间内连续出现次数最多的数的次数。】
- (POJ3368)Frequent values <RMQ 求区间出现次数最多的数出现的次数>
- (POJ3368)Frequent values <RMQ 求区间出现次数最多的数出现的次数>
- 【HDU5751 BestCoder Round 84E】【FFT + 线段树求最值】Eades 最大数出现次数为[1~n]的区间个数
- bzoj 3524 可持久化线段树(统计区间数值出现次数
- HDU 3577 Fast Arrangement(线段树功能:区间更新,查询区间的最大覆盖次数)
- poj 3368 统计区间出现次数最多数个数 RMQ
- 线段树离线处理(区间内出现k次的数有多少个)Codeforces Round #136 (Div. 2)
- hdu4391(线段树查找区间内出现的个数)
- 蓝桥杯-连号区间数(枚举||线段树)
- 1174 区间中最大的数(线段树)
- POJ 3368 线段树,给定区间求连续不降序列的在该区间内出现最多的数
- HDU5091->线段树维护区间覆盖次数&&扫描线
- acmoj - 数蘑菇线段树区间更新
- HDU2665(函数式线段树-区间第K大)
- hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)
- 线段树(区间修改,区间查询)
- asp.net repeater绑定多列,自动补齐TD。修改调试完美版
- 浅谈Windows Phone 7本地数据库的选择
- 浅谈数据集合
- window如何映射网络驱动器,连接到linux(我用的是:CentOS)下的目录?图解
- 【三】WinXP+IIS6 配置Discuz和phpwind论坛完全手册---mysql-essential-5.0.87安装配置
- 函数式线段树(区间数出现次数)
- Jenkins+Maven+SVN publish over ssh plugin--配置solr4.0/solr4.1/solr4.2/solr4.3 开发环境
- 免费开源数据挖掘软件推荐共五个(Orange、RapidMiner等)
- 加入一个组播组
- OpenGL 渲染管线--1
- C指针的用法总结
- 给iphone5一个大屏幕
- 武侠剧的通用手法,悦来客栈是少不了的
- 自由拼音输入法(freepy) 版本2.2编译方案