ZOJ2112 Dynamic Rankings(整体二分)
今天学习了一个奇技淫巧--整体二分。关于整体二分的一些理论性的东西,可以参见XRH的《浅谈数据结构题的几个非经典解法》。然后下面是一些个人的心得体会吧,写下来希望加深一下自己的理解,或者如果有人看了或许也有些帮助。
ZOJ2112是一道典型的带修改的区间第k大的问题,有一些树套树等的数据结构可以在线处理这样的问题。但是当题目并不要求在线处理的时候,其实我们可以选择一下整体二分的思想。
个人对整体二分的理解是这样子的,首先对于修改,即把a[xi]=yi(1<=yi<=C)的时候,我们可以把修改的操作划分成两部分,一部分是yi<=mid,另一部分是yi>mid。首先我们忽略掉yi>mid的操作,将yi<=mid以及询问操作按照输入的顺序执行一遍,这样我们就可以知道<=mid的操作对所有询问的贡献,接下来我们就要根据贡献对修改操作划分成两部分,一部分是答案在<=mid里面的,另外一部分是答案在>mid里面的,对于<=mid的,显然我们可以递归求解(因为>mid的操作对那些<=mid是没有影响的),而对于>mid的来说,<=mid的操作是有影响的,但是<=mid所造成的影响已经算过一遍了,所以对于>mid的来说,其实也是独立的。所以如果我们把答案二分的范围的大小设为C,操作的总数设为n,那么划分到<=mid的操作是n1,>mid的操作是n2时(n1+n2=n)
有 T(n,C)=T(n1,C/2)+T(n2,C/2)+O(nlogC) T(n)=nlogC^2...(也不知道复杂度对不对,可以画一个图来YY一下)
好吧,其实我也不知道上面说了什么,感觉真的蛮难用一两段话将整个思路说出来的。其实总的抽象的来说,就是一开始维护的可能答案的区间是[l,r],
然后我们将所有<=mid的操作作一遍,然后将答案落在[l,mid]的操作(询问和修改)划到一边,将答案落在[mid+1,r]的操作(询问和修改)划到另一边。
#pragma warning(disable:4996)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
using namespace std; #define maxn 300000 struct Query
{
int x, y; // qt==3 [x,y] qt==1||2 a[x]=y
int qt; // query type 1 for increase 2 for decrease 3 for query
int cur; // the current contribution
int k; // the query is the k-th smalleset
int index;
}q[maxn];
int qtop; int a[maxn];
int b[maxn];
int bsize;
int n, m;
int tot;
int ans[maxn];
int ansid; int tmp[maxn];
Query q1[maxn], q2[maxn];
int bit[maxn];
void add(int x, int v)
{
while (x <= n){
bit[x] += v;
x += x&(-x);
}
} int query(int x)
{
int ret = 0;
while (x > 0){
ret += bit[x];
x -= x&(-x);
}
return ret;
} void solve(int head, int tail, int l, int r)
{
if (head > tail) return;
if (l == r){
for (int i = head; i <= tail; ++i){
if (q[i].qt == 3) ans[q[i].index] = l;
}
return;
}
int mid = (l + r) >> 1;
// 将所有<=mid的操作作一遍,tmp[i]存的是[head,tail]里<=mid的操作对询问的贡献
for (int i = head; i <= tail; ++i){
if (q[i].qt == 1 && q[i].y <= mid){
add(q[i].x, 1);
}
else if (q[i].qt == 2 && q[i].y <= mid){
add(q[i].x, -1);
}
else{
tmp[i] = query(q[i].y) - query(q[i].x - 1);
}
}
// 将操作撤销一下
for (int i = head; i <= tail; ++i){
if (q[i].qt == 1 && q[i].y <= mid){
add(q[i].x, -1);
}
else if (q[i].qt == 2 && q[i].y <= mid){
add(q[i].x, 1);
}
}
// 将操作划分成两部分
int l1=0, l2 = 0;
for (int i = head; i <= tail; ++i){
if (q[i].qt == 3){
// 如果前面的数加上当前的数>=q[i].k,说明该询问的可行区间在[l,mid],往左划分
if (q[i].cur + tmp[i] >= q[i].k){
q1[++l1] = q[i];
}
else{
// 否则往右划分,并记下贡献
q[i].cur += tmp[i];
q2[++l2] = q[i];
}
}
else{
if (q[i].y <= mid) q1[++l1] = q[i];
else q2[++l2] = q[i];
}
} for (int i = 1; i <= l1; ++i) {
q[head + i - 1] = q1[i];
}
for (int i = 1; i <= l2; ++i){
q[head + l1 + i - 1] = q2[i];
}
solve(head, head + l1 - 1, l, mid);
solve(head + l1, tail, mid + 1, r);
} int main()
{
int T; cin >> T;
while (T--)
{
scanf("%d%d", &n, &m);
qtop = 0;tot = 0;
for (int i = 1; i <= n; ++i){
scanf("%d", a + i);
b[tot++] = a[i];
q[++qtop].qt = 1;
q[qtop].x = i;
q[qtop].y = a[i];
}
char cmd[4];
int xi, yi,ki;
ansid = 0;
for (int i = 0; i < m; ++i){
scanf("%s", cmd);
if (cmd[0] == 'Q'){
scanf("%d%d%d", &xi, &yi, &ki);
q[++qtop].x = xi; q[qtop].y = yi; q[qtop].k = ki;
q[qtop].qt = 3; q[qtop].cur = 0; q[qtop].index = ++ansid;
}
else{
scanf("%d%d", &xi, &yi);
q[++qtop].x = xi; q[qtop].y = a[xi]; q[qtop].qt = 2;
q[++qtop].x = xi; q[qtop].y = yi; q[qtop].qt = 1;
a[xi] = yi;
b[tot++] = yi;
}
}
sort(b, b + tot);
bsize = unique(b, b + tot) - b; for (int i = 1; i <= qtop; ++i){
if (q[i].qt == 1 || q[i].qt == 2){
q[i].y = lower_bound(b, b + bsize, q[i].y) - b + 1;
}
}
solve(1, qtop, 1, bsize);
for (int i = 1; i <= ansid; ++i){
printf("%d\n", b[ans[i]-1]);
}
}
//system("pause");
return 0;
}
ZOJ2112 Dynamic Rankings(整体二分)的更多相关文章
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 【BZOJ1901】Dynamic Rankings [整体二分]
Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个含 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——整体二分
[题目分析] 上次用树状数组套主席树做的,这次用整体二分去水. 把所有的查询的结果一起进行二分,思路很好. [代码] #include <cstdio> #include <cstr ...
- BZOJ1901: Zju2112 Dynamic Rankings(整体二分 树状数组)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9094 Solved: 3808[Submit][Status][Discuss] Descript ...
- BZOJ 1901 Dynamic Rankings (整体二分+树状数组)
题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...
- 洛谷$P2617\ Dynamic\ Rankings$ 整体二分
正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...
- BZOJ.1901.Dynamic Rankings(整体二分)
题目链接 BZOJ 洛谷 (以下是口胡) 对于多组的询问.修改,我们可以发现: 假设有对p1,p2,p3...的询问,在这之前有对p0的修改(比如+1),且p0<=p1,p2,p3...,那么我 ...
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- ZOJ2112 Dynamic Rankings
题意 Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings ...
随机推荐
- J.U.C 系列之Atomic原子类
一 什么是原子类? 所谓原子类必然是具有原子性的类,原子性操作--原子操作,百度百科中给的定义如下 "原子操作(atomic operation)是不需要synchronized" ...
- 4,Flask 中的 request
每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互 基于HTML + Flask 写一 ...
- NPM安装vue-cli,并创建vue+webpack项目模板
1.安装npm npm 是node.js 的包管理工具, 安装流程地址:https://docs.npmjs.com/cli/install 估计会非常慢,我们可以使用淘宝NPM镜像下载安装:htt ...
- Java重写与重载
重写的规则: 参数列表必须完全与被重写方法的相同: 返回类型必须完全与被重写方法的返回类型相同: 访问权限不能比父类中被重写的方法的访问权限更低.例如:如果父类的一个方法被声明为public,那么在子 ...
- runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)
每一个类对象中都一个对象方法列表(对象方法缓存) 类方法列表是存放在类对象中isa指针指向的元类对象中(类方法缓存) 方法列表中每个方法结构体中记录着方法的名称,方法实现,以及参数类型,其实selec ...
- 剑指Offer - 九度1505 - 两个链表的第一个公共结点
剑指Offer - 九度1505 - 两个链表的第一个公共结点2013-11-24 20:09 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例 ...
- Django笔记 —— 模型
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- 【Count Complete Tree Nodes】cpp
题目: Given a complete binary tree, count the number of nodes. Definition of a complete binary tree fr ...
- jQuery easyuI datagrid 多行编辑
在easyUI 动态绑定部分数据后,需要有部分列可以修改,研究了一天终于搞定.这是小弟的做法,望各位有好招的大侠指点. 1.添加jQuery 和jQuery easyuI的引用. 2.添加id为tt的 ...
- python基础实践(二)
-*-越简单越快乐-*-# -*- coding:utf-8 -*-# Author:sweeping-monkQuestion_1 = "python中的整数运算"Method_ ...