Codeforces Gym101505G:Orchard Division(扫描线+线段树第k大)
题意
给出一个m*m的地图,上面有n个点,现在需要用一个自定义面积的矩形笼罩住恰好n/2个点,并且这个矩形需要有一个点在至少一个角落上,问这个矩形最小的面积是多少。
思路
有点类似于扫描线。将y坐标离散化,沿着x轴扫过去,边加点边查找,注意这里一定要每次加一列(即x相同的时候要全加进去,不然找第k大的时候可能出错),每次查找的时候就找恰好第n/2大的y坐标,然后就可以得到面积了。
考虑到四个角都需要判定,一开始我写了四个又长又臭的函数,后来队友写了一个挺妙的Rotate()函数。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 11;
const LL inf = 2e18;
#define lson l, m, rt<<1
#define rson m + 1, r, rt<<1|1
struct Node {
int x, y;
} p[N];
int yy[N], cy, tree[N<<2], n, m, x, y;
LL ans;
bool cmp(const Node &a, const Node &b) {
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
void Rotate() {
for(int i = 1; i <= n; i++) {
x = p[i].x;
p[i].x = m - p[i].y + 1;
p[i].y = x;
}
}
void build(int l ,int r, int rt) {
tree[rt] = 0;
if(l == r) return ;
int m = (l + r) >> 1;
build(lson); build(rson);
}
void update(int id, int w, int l, int r, int rt) {
tree[rt] += w;
if(l == r) return ;
int m = (l + r) >> 1;
if(id <= m) update(id, w, lson);
else update(id, w, rson);
}
int query(int k, int l, int r, int rt) {
if(tree[rt] < k) return -1;
if(l == r) return tree[rt] == k ? yy[l] : -1;
int m = (l + r) >> 1;
if(tree[rt<<1] >= k) return query(k, lson);
else return query(k - tree[rt<<1], rson);
}
void solve() {
cy = 0;
for(int i = 1; i <= n; i++) yy[++cy] = p[i].y;
sort(yy + 1, yy + 1 + cy);
cy = unique(yy + 1, yy + 1 + cy) - yy - 1;
sort(p + 1, p + 1 + n, cmp);
build(1, cy, 1);
for(int i = 1; i <= n; ) {
for(x = p[i].x ; i <= n && p[i].x == x; i++) {
y = lower_bound(yy + 1, yy + 1 + cy, p[i].y) - yy;
update(y, 1, 1, cy, 1);
}
if(i < n / 2) continue;
int now = query(n / 2, 1, cy, 1);
if(now == -1) continue;
ans = min(ans, 1LL * x * now);
}
Rotate();
}
int main() {
while(~scanf("%d%d", &m, &n)) {
for(int i = 1; i <= n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].x++; p[i].y++;
}
if(n & 1) { puts("-1"); continue; }
ans = inf;
for(int i = 0; i < 4; i++) solve();
if(ans == inf) ans = -1;
printf("%lld\n", ans);
}
return 0;
}
Codeforces Gym101505G:Orchard Division(扫描线+线段树第k大)的更多相关文章
- Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)
Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...
- HDU 3642 - Get The Treasury - [加强版扫描线+线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树
[BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)
Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...
- 【bzoj4491】我也不知道题目名字是什么 离线扫描线+线段树
题目描述 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 输入 第一行n,表示A数组有多少元素接下来一行为n个整数A[i]接下来一个整数Q,表示询问数 ...
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...
- P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)
题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...
- Codeforces 407E - k-d-sequence(单调栈+扫描线+线段树)
Codeforces 题面传送门 & 洛谷题面传送门 深感自己线段树学得不扎实-- 首先特判掉 \(d=0\) 的情况,显然这种情况下满足条件的区间 \([l,r]\) 中的数必须相同,双针扫 ...
随机推荐
- mac系统下虚拟机parallels安装ubuntu 14.04
mac系统很棒,mac下的开发环境也很棒,但有时你还得需要ubuntu开发环境,比如进行嵌入式Linux交叉编译,使用Linaro toolchain… 其实mac系统下使用parallels虚拟机安 ...
- 从Header中获得信息
/// <summary> /// 获得header信息 /// </summary> /// <param name="response">& ...
- 图像滤镜艺术--PS平均(滤镜-模糊-平均)效果
原文:图像滤镜艺术--PS平均(滤镜-模糊-平均)效果 本文介绍PS中滤镜-模糊-平均模糊的效果实现: 这个效果很简单,原理如下: 1,统计全图像素的R,G,B值得和sumR,sumG,sumB; 2 ...
- 使用 Napa 创建并调试一个 Office 内容应用 – Hello World
原文地址:http://simpeng.net/office-add-in/%e4%bd%bf%e7%94%a8-napa-%e5%88%9b%e5%bb%ba%e5%b9%b6%e8%b0%83%e ...
- 逆向工程mybatis-geneator.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfiguration ...
- Mac OS下terminal的快捷键
时隔2年又开始使用Mac OS系统,之前的很多快捷键和常用的命令都忘记了,使用起来确实不方便,效率也低,特别是terminal下,所以对于terminal又找了一下并整理如下,希望对后来的同学也有用: ...
- delphi中pos和Ansipos函数的区别
POS和ANSIPOS的主要区别在于,POS参数多用于是一个字符,而ANSIPOS多用于是多个字符: 例如:i:=pos('a','sssssas'); i:=ansipos('abc','sdabc ...
- 浅析 C++ 调用 Python 模块
浅析 C++ 调用 Python 模块 作为一种胶水语言,Python 能够很容易地调用 C . C++ 等语言,也能够通过其他语言调用 Python 的模块. Python 提供了 C++ 库,使得 ...
- 使用fastjson读取超巨json文件引起的GC问题
项目中需要将巨量数据生成的json文件解析,并写入数据库,使用了 alibaba 的 fastjson,在实践过程中遇到了 GC 问题,记录如下: 数据大约为70万条,文件大小在3~4G左右,使用 f ...
- 你一定能看懂的JDK动态代理
前言:阅读这篇文章前,一定要知道什么是代理模式,具体可以参考这篇文章<设计模式(一):代理模式>. 在<设计模式(一):代理模式>一文中说了,程序员思思买书有两种选择:一种是选 ...