「luogu2617」Dynamic Rankings
「luogu2617」Dynamic Rankings
传送门
树套树直接上树状数组套主席树,常数很大就是了。
树套树参考代码:
/*--------------------------------
Code name: DynamicRanking.cpp
Author: The Ace Bee
This code is made by The Ace Bee
--------------------------------*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rg register
using namespace std;
const int MAXN = 500010;
inline int lowbit(int x) { return x & -x; }
inline int read() {
int s = 0; bool f = false; char c = getchar();
while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
return f ? -s : s;
}
int n, m, a[MAXN], len, b[MAXN], rt[MAXN];
int tot, num[MAXN << 5], lc[MAXN << 5], rc[MAXN << 5];
int cnt[2], tmp[2][20];
struct node{ bool f; int l, r, k; int pos, key; }p[MAXN];
inline void update(int& p, int l, int r, int x, int v) {
if (!p) p = ++tot;
num[p] += v;
if (l == r) return;
int mid = (l + r) >> 1;
if (x <= mid) update(lc[p], l, mid, x, v);
else update(rc[p], mid + 1, r, x, v);
}
inline void HJTupdate(int x, int v) {
int k = lower_bound(b + 1, b + len + 1, a[x]) - b;
for (rg int i = x; i <= n; i += lowbit(i)) update(rt[i], 1, len, k, v);
}
inline int query(int l, int r, int k) {
if (l == r) return l;
int mid = (l + r) >> 1, sum = 0;
for (rg int i = 1; i <= cnt[1]; ++i) sum += num[lc[tmp[1][i]]];
for (rg int i = 1; i <= cnt[0]; ++i) sum -= num[lc[tmp[0][i]]];
if (k <= sum) {
for (rg int i = 1; i <= cnt[1]; ++i) tmp[1][i] = lc[tmp[1][i]];
for (rg int i = 1; i <= cnt[0]; ++i) tmp[0][i] = lc[tmp[0][i]];
return query(l, mid, k);
} else {
for (rg int i = 1; i <= cnt[1]; ++i) tmp[1][i] = rc[tmp[1][i]];
for (rg int i = 1; i <= cnt[0]; ++i) tmp[0][i] = rc[tmp[0][i]];
return query(mid + 1, r, k - sum);
}
}
inline int HJTquery(int l, int r, int k) {
memset(tmp, 0, sizeof tmp), cnt[0] = cnt[1] = 0;
for (rg int i = r; i; i -= lowbit(i)) tmp[1][++cnt[1]] = rt[i];
for (rg int i = l; i; i -= lowbit(i)) tmp[0][++cnt[0]] = rt[i];
return query(1, len, k);
}
int main() {
n = read(), m = read();
for (rg int i = 1; i <= n; ++i) a[i] = read(), b[++len] = a[i];
for (rg int i = 1; i <= m; ++i) {
char s[5]; scanf("%s", s);
p[i].f = (s[0] == 'Q');
if (p[i].f)
p[i].l = read(), p[i].r = read(), p[i].k = read();
else
p[i].pos = read(), p[i].key = read(), b[++len] = p[i].key;
}
sort(b + 1, b + len + 1);
len = unique(b + 1, b + len + 1) - b - 1;
for (rg int i = 1; i <= n; ++i) HJTupdate(i, 1);
for (rg int i = 1; i <= m; ++i) {
if (p[i].f)
printf("%d\n", b[HJTquery(p[i].l - 1, p[i].r, p[i].k)]);
else {
HJTupdate(p[i].pos, -1);
a[p[i].pos] = p[i].key;
HJTupdate(p[i].pos, 1);
}
}
return 0;
}
整体二分的话就把修改看做减去开始的再加上后来的,跑得比树套树快远了~
整体二分参考代码:
#include <algorithm>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 2e5 + 5, INF = 1e9;
int n, m, q, a[_], tr[_], res[_];
int num; struct node { int opt, id, l, r, k; } t[_ << 1], tt1[_ << 1], tt2[_ << 1];
inline void update(int x, int v) { for (rg int i = x; i <= n; i += i & -i) tr[i] += v; }
inline int query(int x) { int res = 0; for (rg int i = x; i >= 1; i -= i & -i) res += tr[i]; return res; }
inline void solve(int ql, int qr, int l, int r) {
if (ql > qr || l > r) return ;
if (l == r) { for (rg int i = ql; i <= qr; ++i) if (t[i].opt == 1) res[t[i].id] = l; return ; }
int mid = (l + r) >> 1, p1 = 0, p2 = 0;
for (rg int i = ql; i <= qr; ++i) {
if (t[i].opt == 0) {
if (t[i].l <= mid) update(t[i].r, t[i].k), tt1[++p1] = t[i]; else tt2[++p2] = t[i];
} else {
int cnt = query(t[i].r) - query(t[i].l - 1);
if (cnt >= t[i].k) tt1[++p1] = t[i]; else t[i].k -= cnt, tt2[++p2] = t[i];
}
}
for (rg int i = 1; i <= p1; ++i) if (tt1[i].opt == 0) update(tt1[i].r, -tt1[i].k);
for (rg int i = 1; i <= p1; ++i) t[ql + i - 1] = tt1[i];
for (rg int i = 1; i <= p2; ++i) t[ql + p1 + i - 1] = tt2[i];
solve(ql, ql + p1 - 1, l, mid), solve(ql + p1, qr, mid + 1, r);
}
int main() {
read(n), read(m);
for (rg int i = 1; i <= n; ++i) read(a[i]), t[++num] = (node) { 0, 0, a[i], i, 1 };
char s[5];
for (rg int l, r, k, i = 1; i <= m; ++i) {
scanf("%s", s);
if (s[0] == 'Q') read(l), read(r), read(k), t[++num] = (node) { 1, ++q, l, r, k };
else read(l), read(r), t[++num] = (node) { 0, 0, a[l], l, -1 }, t[++num] = (node) { 0, 0, a[l] = r, l, 1 };
}
solve(1, num, -INF, INF);
for (rg int i = 1; i <= q; ++i) printf("%d\n", res[i]);
return 0;
}
「luogu2617」Dynamic Rankings的更多相关文章
- iOS 9,为前端世界都带来了些什么?「译」 - 高棋的博客
2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
随机推荐
- UDP协议 sendto 和 recvfrom 浅析与示例
UDP(user datagram protocol)用户数据报协议,属于传输层. UDP是面向非连接的协议,它不与对方建立连接,而是直接把数据报发给对方.UDP无需建立类如三次握手的连接,使得通信效 ...
- 解析C语言编程对缓冲区的理解
转载自:http://soft.chinabyte.com/database/47/12481547.shtml 下面介绍缓冲区的知识. 一.什么是缓冲区 缓冲区又称为缓存,它是内存空间的一部分.也就 ...
- Docker容器CPU限制选项测试
目录 Docker容器CPU限制选项测试 参考 实验环境 --cpu-shares选项 测试 结论 --cpus选项 测试 结论 --cpuset-cpus选项 测试 结论 Docker容器CPU限制 ...
- Apache POI详解
一 :简介 开发中经常会设计到excel的处理,如导出Excel,导入Excel到数据库中,操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel Apache ...
- mysql的一些不常用语句
今天写项目,用的ThinkPHP,写的时候有点费劲,原因嘛 无非是对框架或者mysql的一些知识的遗忘. 1.为了配合ThinkPHP中的控制器,需要修改数据库中表名,一时想不起来,幸好有百度,问题很 ...
- 【代码审计】VAuditDemo 前台搜索注入
在search.php中 $_GET['search']未经过任何过滤传入到$query的执行语句中
- Spring Boot 学习方法论-如何正确的入门 Spring Boot
想要入门 Spring Boot,那么什么样的教程是符合初学者学习的(没有太多的Java基础但有一些程序基础或者软件编程知识). 这恰好能够勾出很多问题,比如是文章图文教程适合还是视频教程适合零基础初 ...
- Spring Boot RestApi 测试教程 Mock 的使用
测试 Spring Boot Web 的时候,我们需要用到 MockMvc,即系统伪造一个 mvc 环境.本章主要编写一个基于 RESTful API 正删改查操作的测试用例.本章最终测试用例运行结果 ...
- EXPOSE ocker run -P 时,会自动随机映射 EXPOSE 的端口
EXPOSE 声明端口 格式为 EXPOSE <端口1> [<端口2>...]. EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用 ...
- 通过js检测浏览器支持的字体,从而显示支持的字体,让用户选择。
http://www.zhangxinxu.com/wordpress/2018/02/js-detect-suppot-font-family/ 本文根据张鑫旭文章. 字体函数: var dataF ...