【BZOJ 1901】【ZJU 2112】Dynamic Rankings
http://www.lydsy.com/JudgeOnline/problem.php?id=1901
重新用整体二分写了一下。
整体二分的思想详见论文。
貌似带修区间k大和静态区间k大都是\(O(n\log^2n)\)。
cdq是对时间分治,整体二分是对答案分治。
对于动态区间k大怎么实现我还想了很长时间呢,感觉模板题都想这么长时间。。。
动态区间k大的关键步骤是把修改变成两个操作,删除和插入。
这样在一个分治函数内部就可以扫时间轴然后在特定权值范围内的删除和插入分别在bits上-1和+1。
相比较在线bits套主席树,离线整体二分跑得飞快。
离散化后跑得能快一点,不离散的话时间复杂度就是\(O(n\log n\log 10^9)\),离散的话时间复杂度是\(O(n\log^2n)\)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10003;
struct node {int x, y, k, op, id;} B[N << 2], q1[N << 2], q2[N << 2];
int tot = 0, a[N], n, m, bits[N << 1], top = 0, H[N << 1], cnt = 0;
int ans[N], id[N << 2], anstot = 0, que[N << 1], q1len, q2len;
void add(int x, int flag) {for (; x <= n; x += (x & (-x))) bits[x] += flag;}
int sum(int x) {int ret = 0; for (; x; x -= (x & (-x))) ret += bits[x]; return ret;}
void solve(int p, int q, int l, int r) {
	if (p > q) return;
	if (l == r) {
		for (int i = p; i <= q; ++i)
			if (B[i].op == 3)
				ans[B[i].id] = l;
		return;
	}
	int mid = (l + r) >> 1;
	for (int i = p; i <= q; ++i) {
		if (B[i].op != 3) {
			if (B[i].y <= mid)
				add(B[i].x, B[i].op);
		}
		else que[i] = sum(B[i].y) - sum(B[i].x - 1);
	}
	for (int i = p; i <= q; ++i)
		if (B[i].op != 3 && B[i].y <= mid) add(B[i].x, -B[i].op);
	q1len = q2len = 0;
	for (int i = p; i <= q; ++i)
		if (B[i].op != 3) {
			if (B[i].y > mid) q2[++q2len] = B[i];
			else q1[++q1len] = B[i];
		} else {
			if (que[i] >= B[i].k) q1[++q1len] = B[i];
			else B[i].k -= que[i], q2[++q2len] = B[i];
		}
	int tmp = p - 1;
	for (int i = 1; i <= q1len; ++i)
		B[++tmp] = q1[i];
	for (int i = 1; i <= q2len; ++i)
		B[++tmp] = q2[i];
	tmp = p + q1len - 1;
	solve(p, tmp, l, mid);
	solve(tmp + 1, q, mid + 1, r);
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
		B[++tot] = (node) {i, a[i], 0, 1, 0};
		H[++cnt] = a[i];
	}
	int x, y, k;
	char c[2];
	for (int i = 1; i <= m; ++i) {
		scanf("%s", c);
		if (c[0] == 'Q') {
			scanf("%d%d%d", &x, &y, &k);
			B[++tot] = (node) {x, y, k, 3, ++anstot};
		} else {
			scanf("%d%d", &x, &y);
			B[++tot] = (node) {x, a[x], 0, -1, 0};
			B[++tot] = (node) {x, y, 0, 1, 0};
			H[++cnt] = (a[x] = y);
		}
	}
	stable_sort(H + 1, H + cnt + 1);
	cnt = unique(H + 1, H + cnt + 1) - H;
	for (int i = 1; i <= tot; ++i)
		if (B[i].op != 3)
			B[i].y = lower_bound(H + 1, H + cnt, B[i].y) - H;
	solve(1, tot, 1, cnt - 1);
	for (int i = 1; i <= anstot; ++i) printf("%d\n", H[ans[i]]);
	return 0;
}
【BZOJ 1901】【ZJU 2112】Dynamic Rankings的更多相关文章
- 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值  树状数组套主席树模板题
		达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ... 
- 【bzoj 1901】Zju2112 Dynamic Rankings
		Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是 ... 
- 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统   树状数组套线段树
		外面是树状数组,里面是动态开点线段树,对于查询我们先把有关点找出来,然后一起在线段树上行走,这样就是单个O(log2)的了 #include <cstdio> #include <v ... 
- 【BZOJ】【1901】【Zju2112】 Dynamic Rankings
		再填个坑. 动态维护区间第K大(带单点修改) 首先裸的区间第K大我们是用的[前缀和]思想,实现O(n)预处理,O(1)找树查询,那么如果是动态的呢?我们可以利用树状数组(BIT)的思想,进行O(log ... 
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
		题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ... 
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
		1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ... 
- 【BZOJ】3052: [wc2013]糖果公园
		http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ... 
- 【BZOJ】3319: 黑白树
		http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ... 
- 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)
		http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ... 
随机推荐
- dijkstra spfa prim kruskal 总结
			最短路和最小生成树应该是很早学的,大家一般都打得烂熟,总结一下几个问题 一 dijkstra O((V+E)lgV) //V节点数 E边数 dijkstra不能用来求最长路,因为此时局部最优解已经 ... 
- 【洛谷 T47488】 D:希望 (点分治)
			题目链接 看到这种找树链的题目肯定是想到点分治的. 我码了一下午,\(debug\)一晚上,终于做到只有两个点TLE了. 我的是不完美做法 加上特判\(A\)了这题qwq 记录每个字母在母串中出现的所 ... 
- node起本地服务器以及实现代理,前端接口转发
			上一篇文章写了使用docker来做nginx镜像实现本地的页面代理以及接口转发,但是需要下载docker,这个对于很多人来说还是显得比较麻烦,于是这个文章就是介绍如何只用node就可以代理本地的页面和 ... 
- thread_info&内核栈
			转载:http://blog.chinaunix.net/uid-22548820-id-2125152.html 之所以将thread_info结构称之为小型的进程描述符,是因为在这个结构中并没有直 ... 
- inetdev_init && inetdev_destroy
			inetdev_init为传入设备分配和绑定ip控制块,查看其调用关系如下: fs_initcall(inet_init)---->inet_init---->ip_init----> ... 
- 4.FireDAC组件快照 二
			TFDUpdateSQL 生成添加,删除,修改SQL语句 TFDMetaInfoQuery 查询数据源信息 TFDEventAlerter 负责处理数据库事件通知 使用TFDEventAlerter类 ... 
- angular数据绑定---js全局学习
			<!DOCTYPE html> <html ng-app> <head> <title>Simple app</title> </he ... 
- mac10.9下安装Android
			这里记录一下mac下安装android比较快捷的方法 首先,到这里下载Android SDK,这个是集成的,所有工具一应俱全,免去了下载一堆东西的烦恼.具体包括如下: Eclipse + ADT pl ... 
- [ Linux ] 服务器更换硬盘
			服务器型号:ThinkServer RD650操作系统:Red Hat 6.7业务用途:生产环境监控机 接到机房邮件通知,告知某台服务器硬盘告警,并提供了设备SN号和机柜位置.根据提供想相关信息找到对 ... 
- hrbust - 2239
			影子模仿术 Time Limit: 500 MS Memory Limit: 32768 K Total Submit: 7(5 users) Total Accepted: 2(2 users) R ... 
