BZOJ1901——Zju2112 Dynamic Rankings
2024-08-22 01:00:41
1、题目大意:区间第k小,有单点修改
2、分析:这个是树状数组套线段树,也是主席树。。。。为什么主席树这么多QAQ
就是树套树的那种插入什么的,注意啊,一定要动态开内存。。不然会爆。。
然后算答案有两种算法,一种是二分答案,然后算一下,另一种就是把logn棵线段树的指针都存一下,
然后再递归找第k大的时候,我们就可以暴力枚举这些指针,别忘了维护他们
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; struct segment{ segment *ls, *rs; int num; } *root[10010], ft[11000010]; int cnt; int a[10010]; int n, m; inline void tree_insert(segment* &p, int l, int r, int value){ if(p == NULL) p = &ft[cnt ++]; if(l == r){ p -> num ++; return; } int mid = (l + r) / 2; if(value <= mid) tree_insert(p -> ls, l, mid, value); else tree_insert(p -> rs, mid + 1, r, value); p -> num = 0; if(p -> ls) p -> num += p -> ls -> num; if(p -> rs) p -> num += p -> rs -> num; } inline void tree_Delete(segment* &p, int l, int r, int value){ if(p == NULL) p = &ft[cnt ++]; if(l == r){ p -> num --; return; } int mid = (l + r) / 2; if(value <= mid) tree_Delete(p -> ls, l, mid, value); else tree_Delete(p -> rs, mid + 1, r, value); p -> num = 0; if(p -> ls) p -> num += p -> ls -> num; if(p -> rs) p -> num += p -> rs -> num; } inline int tree_lessk(segment* &p, int l, int r, int value){ if(!p) return 0; if(l == r) return p -> num; int mid = (l + r) / 2; int ret = 0; if(value <= mid) ret += tree_lessk(p -> ls, l, mid, value); else { if(p -> ls) ret += p -> ls -> num; ret += tree_lessk(p -> rs, mid + 1, r, value); } return ret; } inline void insert(int x, int y){ for(; x <= n; x += (x & -x)) tree_insert(root[x], 0, 1000000000, y); } inline void Delete(int x, int y){ for(; x <= n; x += (x & -x)) tree_Delete(root[x], 0, 1000000000, y); } inline int lessk(int x, int y){ int ret = 0; for(; x > 0; x -= (x & -x)) ret += tree_lessk(root[x], 0, 1000000000, y); return ret; } int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++){ scanf("%d", &a[i]); insert(i, a[i]); } char str[2]; int x, y, z; for(int i = 1; i <= m; i ++){ scanf("%s", str); scanf("%d%d", &x, &y); if(str[0] == 'Q'){ scanf("%d", &z); int l = 0, r = 1000000000; while(l < r){ int mid = (l + r) / 2; if(lessk(y, mid) - lessk(x - 1, mid) >= z) r = mid; else l = mid + 1; } printf("%d\n", l); } else{ Delete(x, a[x]); a[x] = y; insert(x, a[x]); } } return 0; }
最新文章
- 《javascript权威指南》读书笔记——第二篇
- 【转】段错误调试神器 - Core Dump详解
- 打造一个有感觉的vim(四)
- 素数筛 uva 543
- php大力力 [010节]PHP常量
- Linux启动过程详解 (转)
- adb 工具学习
- Hibernate映射类型对照表
- 深入了解overflow
- 【模拟】FOJ 2244 Daxia want to buy house
- 主流H.264编码器对比测试 (MSU出品)
- PHP后台传值
- WebStorm 使用快捷键大全
- SQL注入(一)普通型注入
- yali项目的slider
- UISearchBar的扩展使用
- Ajax.Nodejs.跨域访问
- jackson 流式API
- BalkanOI 2018 Parentrises(贪心+基础DP)
- Spring Boot IoC 容器初始化过程
热门文章
- C#开发和调用Web Service
- js 连接地址分析
- ecshop 影响全局的标量lib_main.php
- yourphp超出20记录自动删除
- Intent启动一个新的页面
- ERROR 2002 (HY000): Can&#39;t connect to local MySQL server through socket &#39;/var/lib/mysql/mysql.sock&#39; (2)--MySQL错误
- YII2数据库依赖缓存
- Yii2 数据操作Query Builder(转)
- Mono资源
- 【转载】 C中的access函数