#4604. The kth maximum number(整体二分 + 树套树)

#4604. The kth maximum number

给定一个大小不超过5×1055 \times 10 ^ 55×105的矩形区域,有一些点有点权。

每次询问给定x1,y1,x2,y2,kx_1, y_1, x_2, y_2, kx1,y1,x2,y2,k问以x1,y1x_1, y_1x1,y1为右下角,x2,y2x_2, y_2x2,y2为左上角的矩形中权值第kkk大是多少。

其实于P1527 [国家集训队]矩阵乘法是基本差不多的,就是矩形的大小变大了,无法进行二维树状数组操作

但是,矩形数点不就是一个二维偏序问题嘛,可以树套树来解决,于是我们有了如下的做法,

考虑整体二分,

先对x,yx, yx,y进行离散化(保证常数小一点吧),对每个横左边建立一颗主席树,同时用树状数组维护,

于是在二分过程中,我们对每个点的修改操作,直接修改即可,同时对主席树加上内存回收机制,这样可以保证不会炸空间,

之后对每个矩阵的查询,我们只要在区间[x1,x2][x_1, x_2][x1,x2]的主席树上查询值在[y1,y2][y_1, y_2][y1,y2]有多少即可,

整体复杂度O(nlog⁡3n)O(n \log ^ 3 n)O(nlog3n),由于nnn比较小,实测跑得还是挺快的。

#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 10;int X[N], Y[N], V[N], ans[N], n, m, nn, mm, tot;int root[N], ls[N * 300], rs[N * 300], sum[N * 300], stk[N * 300], top, num;void update(int &rt, int l, int r, int x, int v) {if (!rt) {if (top) {rt = stk[top--];}else {rt = ++num;}}sum[rt] += v;if (l == r) {return ;}int mid = l + r >> 1;if (x <= mid) {update(ls[rt], l, mid, x, v);}else {update(rs[rt], mid + 1, r, x, v);}
}int A[50], B[50], cnt1, cnt2;int query(int l, int r, int L, int R) {if (l >= L && r <= R) {int res = 0;for (int i = 1; i <= cnt1; i++) {res -= sum[A[i]];}for (int i =1 ; i <= cnt2; i++) {res += sum[B[i]];}return res;}int mid = l + r >> 1, res = 0, A1[50], B1[50];if (L <= mid) {for (int i = 1; i <= cnt1; i++) {A1[i] = A[i];A[i] = ls[A[i]];}for (int i = 1; i <= cnt2; i++) {B1[i] = B[i];B[i] = ls[B[i]];}res += query(l, mid, L, R);for (int i = 1; i <= cnt1; i++) {A[i] = A1[i];}for (int i = 1; i <= cnt2; i++) {B[i] = B1[i];}}if (R > mid) {for (int i = 1; i <= cnt1; i++) {A1[i] = A[i];A[i] = rs[A[i]];}for (int i = 1; i <= cnt2; i++) {B1[i] = B[i];B[i] = rs[B[i]];}res += query(mid + 1, r, L, R);for (int i = 1; i <= cnt1; i++) {A[i] = A1[i];}for (int i = 1; i <= cnt2; i++) {B[i] = B1[i];}}return res;
}inline int lowbit(int x) {return x & (-x);
}void update(int x, int y, int v) {while (x <= nn) {update(root[x], 1, mm, y, v);x += lowbit(x);}
}int get_sum(int l, int r, int L, int R) {if (l > r || L > R) {return 0;}cnt1 = cnt2 = 0;for (int i = l - 1; i; i -= lowbit(i)) {A[++cnt1] = root[i];}for (int i = r; i; i -= lowbit(i)) {B[++cnt2] = root[i];}return query(1, mm, L, R);
}struct Res {int x1, y1, x2, y2, v, id, op;
}q[N], q1[N], q2[N];void solve(int l, int r, int L, int R) {if (L > R || l > r) {return ;}if (l == r) {for (int i = L; i <= R; i++) {if (q[i].op == 2) {ans[q[i].id] = l;}}return ;}int mid = l + r >> 1, cnt1 = 0, cnt2 = 0;for (int i = L; i <= R; i++) {if (q[i].op == 1) {if (q[i].v > V[mid]) {update(q[i].x1, q[i].y1, 1);q2[++cnt2] = q[i];}else {q1[++cnt1] = q[i];}}else {int cur = get_sum(q[i].x1, q[i].x2, q[i].y1, q[i].y2);if (cur >= q[i].v) {q2[++cnt2] = q[i];}else {q[i].v -= cur;q1[++cnt1] = q[i];}}}for (int i = 1; i <= cnt2; i++) {if (q2[i].op == 1) {update(q2[i].x1, q2[i].y1, -1);}}for (int i = 1; i <= cnt1; i++) {q[L + i - 1] = q1[i];}for (int i = 1; i <= cnt2; i++) {q[L + cnt1 + i - 1] = q2[i];}solve(l, mid, L, L + cnt1 - 1), solve(mid + 1, r, L + cnt1, R);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d", &n, &m);for (int i = 1, op; i <= m; i++) {scanf("%d", &op);if (op & 1) {int x, y, v;scanf("%d %d %d", &x, &y, &v);q[i] = {x, y, 0, 0, v, 0, 1};X[++tot] = x, Y[tot] = y, V[tot] = v;}else {int x1, y1, x2, y2, v;scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &v);q[i] = {x1, y1, x2, y2, v, i, 2};}}sort(X + 1, X + 1 + tot), sort(Y + 1, Y + 1 + tot), sort(V + 1, V + 1 + tot);nn = unique(X + 1, X + 1 + tot) - (X + 1);mm = unique(Y + 1, Y + 1 + tot) - (Y + 1);tot = unique(V + 1, V + 1 + tot) - (V + 1);for (int i = 1; i <= m; i++) {if (q[i].op & 1) {q[i].x1 = lower_bound(X + 1, X + 1 + nn, q[i].x1) - X;q[i].y1 = lower_bound(Y + 1, Y + 1 + mm, q[i].y1) - Y;}else {q[i].x1 = lower_bound(X + 1, X + 1 + nn, q[i].x1) - X;q[i].y1 = lower_bound(Y + 1, Y + 1 + mm, q[i].y1) - Y;q[i].x2 = upper_bound(X + 1, X + 1 + nn, q[i].x2) - X;q[i].y2 = upper_bound(Y + 1, Y + 1 + mm, q[i].y2) - Y;q[i].x2--, q[i].y2--;}}for (int i = 1; i <= m; i++) {ans[i] = -1;}solve(0, tot, 1, m);for (int i = 1; i <= m; i++) {if (ans[i] != -1) {if (ans[i] == 0) {puts("NAIVE!ORZzyz.");}else {printf("%d\n", V[ans[i]]);}}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《WTM送书活动:向更遥远的星辰大海起航~》

点击上方蓝字关注我们吧是的,没错~这一篇不是大老刘写的 哈哈~啥? 你想知道为啥? 大老刘为了你们不加班,熬夜改BUG,姑娘不乐意了...然后...后面请自行脑补~哎~生活还要继续鸭....那么,接下来由我陪大家唠一段儿~ 单口...各位看官老爷们:注意了!第一件事情呢我们的WTM框…

Java中的对象一定在堆上分配吗?

首先&#xff0c;为解释这个问题&#xff0c;需要的基本知识如下&#xff08;如果对以下概念不太熟悉&#xff0c; 可以先了解下&#xff09;&#xff1a; 1.JVM内存结构&#xff0c;传送门 2.即时编译&#xff08;JIT&#xff09;&#xff0c;传送门 3. 逃逸分析&#xff0c;…

最全的 netcore 3.0 升级实战方案

1、哈喽大家中秋节&#xff08;后&#xff09;好呀&#xff01;感觉已经好久没有写文章了&#xff0c;但是也没有偷懒哟&#xff0c;我的视频教程《系列一、NetCore 视频教程&#xff08;Blog.Core&#xff09;》也已经录制八期了&#xff0c;还在每周末同步更新中&#xff0c;…

微软发布.Net Core 3.0 RC1,最终版本定于9月23日

2019.9.17 微软 宣布推出.NET Core 3.0 Release Candidate 1。就像Preview 9一样&#xff0c;主要专注于为 .NET Core 3.0 发布最终版本 。现在变得非常非常接近。将在9月23日.NET Conf上发布最终版本。.NET Core 3.0是从仅支持Windows传统的 .NET框架向更现代化的开源实现过渡…

JVM内存结构 VS Java内存模型 VS Java对象模型

Java作为一种面向对象的&#xff0c;跨平台语言&#xff0c;其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似&#xff0c;很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模型和Java对象模型&#xff0c;这就是三个截然不同的概念&…

迫于误解压力,RMS从自由软件基金会与MIT离职

自由软件基金会官网显示&#xff0c;基金会创始人兼主席、自由软件运动发起人 Richard M. Stallman&#xff08;RMS&#xff09;辞去主席职务并辞去董事会职务。而另一边&#xff0c;stallman.org 邮件列表显示&#xff0c;RMS 已经从麻省理工学院&#xff08;MIT&#xff09;计…

让人迷茫的三十岁!从专业技能、行业知识和软实力谈一下!

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区合伙人&#xff01;我今年三十岁&#xff0c;我很迷茫&#xff0c;不知道未来该选择什么发展方向。这是我无意中在社区微信群中看到的一位年轻的开发者说的话&#xff0c;之前他也经常会在技术群…

误用.Net Redis客户端工具CSRedisCore,自己挖坑自己填

前导  上次Redis MQ分布式改造完成之后&#xff0c; 编排的容器稳定运行了一个多月&#xff0c;昨天突然收到ETL端同事通知&#xff0c;没有采集到解析日志了。赶紧进服务器看了一下&#xff0c;用于数据接收的receiver容器挂掉了&#xff0c; 尝试docker container start [c…

Java——类加载机制

** 一、什么是类的加载 ** 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内&#xff0c;然后在堆区创建一个java.lang.Class对象&#xff0c;用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class…

.NET中国峰会议题征集

月初做的调查《》&#xff0c;参与人数576人&#xff0c;愿意参与分享.NET Core经验的142人&#xff0c;今天发起分会场主题演讲和闪电演讲议题.2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.N…

一些学习教程资料等你来拿

近期整理自己的云盘中发现近年来私藏了很多学习资料和教程&#xff0c;本着独乐乐不如众乐乐的精神&#xff0c;特将其分享出来供有兴趣的童鞋学习。进入公众号&#xff0c;输入关键词"敏捷"/"agile"/"scrum"&#xff0c;即可获得敏捷开发类别的…

Java——编译与反编译

** 一、基础知识 ** 1.1 编程语言 在介绍编译和反编译之前&#xff0c;我们先来简单介绍下编程语言&#xff08;Programming Language&#xff09;。编程语言&#xff08;Programming Language&#xff09;分为低级语言&#xff08;Low-level Language&#xff09;和高级语…

程序员自家种水果,新鲜包邮配送

上次猕猴桃的活动<好多小伙伴&#xff0c;买了一箱尝过后又下单了好几箱。事实证明&#xff0c;品质才是销量的最佳保证。有些粉丝找到我说&#xff0c;自己家也有果园自己种水果&#xff0c;都是当天采摘当天发货的纯天然水果。于是他们给我寄了一些自家种的苹果、香瓜、冬…

【招聘(广州)】-年薪30W起-自助打印领域业内第一

印萌是一家为高校打印店提供整套“无人自助打印”解决方案的互联网科技公司&#xff0c;已获得数百万元融资&#xff0c;公司正向盈利。目前产品覆盖清华大学、北京大学、中山大学、复旦大学、浙江大学等700多所高校&#xff0c;多达1800间打印店&#xff0c;累计为全国1200万大…

尾递归

1、递归 简单的来说递归就是一个函数直接或间接地调用自身&#xff0c;是为直接或间接递归。一般来说&#xff0c;递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时&#xff0c;递归前进&#xff1b;当边界条件满足时&#xff0c;递归返回。 用递归需要注意以…

多场景抢红包业务引发.NETCore下使用适配器模式实现业务接口分离

事情的起因我们公司现有一块业务叫做抢红包&#xff0c;最初的想法只是实现了一个初代版本&#xff0c;就是给指定的好友单发红包&#xff0c;随着业务的发展&#xff0c;发红包和抢红包的场景也越来越多&#xff0c;目前主要应用的场景有&#xff1a;单聊发红包、群聊发红包、…

设计模式——创建型模型

目录 单例模式&#xff08;singleton&#xff09;构建模式&#xff08;Builder&#xff09;原型模式&#xff08;Prototype&#xff09;工厂方法模式&#xff08;Factory&#xff09;抽象工厂模式&#xff08;Abstract Factory&#xff09; ** 一、5种创建型模型 ** 1.1 单…

【C】KoobooJson在asp.net core中的使用

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。本文链接&#xff1a;https://blog.csdn.net/j_teng/article/details/100924973“KoobooJson是一款体积小巧没有任何依赖且性能表现强劲的Json工具…

【DevOps进行时】C/S端界面自动化测试:微软UIAutomation实践

在界面自动化测试领域里存在许多流行的自动化测试工具&#xff0c;例如目前比较受欢迎的开源自动化工具Selenium、Katalon&#xff1b;HP旗下知名的商业软件Unified Functional Testing(更名前叫QTP)&#xff1b;隶属于IBM以数据驱动测试的RTF&#xff08;Rational Functional …

代码编辑器横评:为什么 VS Code 能拔得头筹

2015 年 4 月 29 日的 Build 大会上&#xff0c;微软发布了 Visual Studio Code 第一个预览版本。短短四年时间里&#xff0c;VS Code 高速成长。根据 2019 年 2 月的 PYPL Top IDE index 的排名&#xff0c;VS Code 的涨势迅猛&#xff0c;在所有编辑器与 IDE 中排名第六&…