省队集训 Day3 杨北大
【题目大意】
给出平面上$n$个点$(x_i, y_i)$,请选择一个不在这$n$个点之内的点$(X, Y)$,定义$(X, Y)$的价值为往上下左右四个方向射出去直线,经过$n$个点中的数量的最小值。
Task 1: 求价值最大的点
Task 2: 求价值最大的点的个数
保证Task 1和Task 2各占50pts。
对于30%的数据,$n \leq 200$;
对于60%的数据,$n \leq 5000$;
对于100%的数据,$n \leq 300000$。
每档数据中,50%保证$1 \leq x_i, y_i \leq n$;50%保证$1 \leq x_i, y_i \leq 10^9$。
【题解】
考场写了60分暴力。。签到题不会打系列。
回家路上认真想了想,离散后把每个位置用vector存起来。
二分答案$x$,那么得到的就是若干合法区间(有横的也有竖的),那么一个点只要被一横一竖两个区间同时经过,就有1的贡献,先不考虑$(X, Y)$在$n$个点中的情况,那么这样就能用扫描线+BIT解决了。
预处理出来对于关键点的贡献,统计的时候减去即可。
复杂度$O(nlog^2n)$。
Orz YangPKU
# include <vector>
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 3e5 + ;
const int mod = 1e9+; inline int getint() {
int x = ; char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = (x<<) + (x<<) + ch - '', ch = getchar();
return x;
} int n, x[M], y[M], X, Y, ori[M];
vector<int> psa, psb;
vector<int> vx[M], vy[M]; int xlen[M], ylen[M]; struct option {
int op, x, yl, yr, del;
option() {}
option(int op, int x, int yl, int yr, int del = ) : op(op), x(x), yl(yl), yr(yr), del(del) {}
friend bool operator < (option a, option b) {
return a.x < b.x || (a.x == b.x && a.op < b.op);
}
}o[M * ]; int on; struct BIT {
# define lb(x) (x&(-x))
ll c[M]; int n;
inline void set(int _n) {
n = _n; memset(c, , sizeof c);
}
inline void edt(int x, int d) {
for (; x<=n; x+=lb(x)) c[x] += d;
}
inline ll sum(int x) {
ll ret = ;
for (; x; x-=lb(x)) ret += c[x];
return ret;
}
inline ll sum(int x, int y) {
if(x > y) return ;
return sum(y) - sum(x-);
}
# undef lb
}T; inline ll chk(int x) {
ll ans = ;
on = ;
for (int i=, l, r; i<=X; ++i) {
if(xlen[i] >= x + x) {
l = vx[i][x-] + , r = vx[i][xlen[i]-x] - ;
o[++on] = option(, i, l, r);
}
}
for (int i=, l, r; i<=Y; ++i) {
if(ylen[i] >= x + x) {
l = vy[i][x-] + , r = vy[i][ylen[i]-x] - ;
o[++on] = option(, l, i, i, );
o[++on] = option(, r+, i, i, -);
}
}
sort(o+, o+on+);
for (int i=; i<=on; ++i) {
if(o[i].op == ) T.edt(o[i].yl, o[i].del);
else ans += T.sum(o[i].yl, o[i].yr);
}
for (int i=; i<=n; ++i) ans -= (ori[i] >= x);
return ans;
} int main() {
int type;
n = getint(); type = getint();
for (int i=; i<=n; ++i) psa.push_back(x[i] = getint()), psb.push_back(y[i] = getint());
sort(psa.begin(), psa.end()); psa.erase(unique(psa.begin(), psa.end()), psa.end()); X = psa.size();
sort(psb.begin(), psb.end()); psb.erase(unique(psb.begin(), psb.end()), psb.end()); Y = psb.size();
for (int i=; i<=n; ++i) x[i] = lower_bound(psa.begin(), psa.end(), x[i]) - psa.begin() + , y[i] = lower_bound(psb.begin(), psb.end(), y[i]) - psb.begin() + ;
for (int i=; i<=n; ++i) vx[x[i]].push_back(y[i]), vy[y[i]].push_back(x[i]);
for (int i=; i<=X; ++i) {
sort(vx[i].begin(), vx[i].end());
xlen[i] = vx[i].size();
}
for (int i=; i<=Y; ++i) {
sort(vy[i].begin(), vy[i].end());
ylen[i] = vy[i].size();
}
for (int i=, xid, yid; i<=n; ++i) {
xid = lower_bound(vy[y[i]].begin(), vy[y[i]].end(), x[i]) - vy[y[i]].begin();
yid = lower_bound(vx[x[i]].begin(), vx[x[i]].end(), y[i]) - vx[x[i]].begin();
ori[i] = min(min(xid, ylen[y[i]]-xid-), min(yid, xlen[x[i]]-yid-));
}
int l = , r = n/, mid, ans = -; T.set(Y); ll t;
while() {
if(r - l <= ) {
for (int i=r; i>=l; --i) {
if(t = chk(i)) {
ans = i;
break;
}
}
break;
}
mid = l+r>>;
if(chk(mid)) l = mid;
else r = mid;
}
assert(ans != -);
if(type == ) printf("%d\n", ans);
else printf("%lld\n", t);
return ;
}
省队集训 Day3 杨北大的更多相关文章
- 省队集训Day3 light
[问题描述] “若是万一琪露诺(俗称 rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她一定也答不上来.” ...
- 省队集训Day3 tree
[题目描述] RHL 有一天看到 lmc 在玩一个游戏. “愚蠢的人类哟,what are you doing”,RHL 说. “我在玩一个游戏.现在这里有一个有 n 个结点的有根树,其中有 m 个叶 ...
- bzoj4171 or 省队集训day3 chess: Rhl的游戏
[题目描述] RHL最近迷上一个小游戏:Flip it.游戏的规则很简单,在一个N*M的格子上,有一些格子是黑色,有一些是白色.每选择一个格子按一次,格子以及周围边相邻的格子都会翻转颜色(边相邻指至少 ...
- FJ省队集训DAY3 T2
思路:如果一个DAG要的路径上只要一条边去切掉,那么要怎么求?很容易就想到最小割,但是如果直接做最小割会走出重复的部分,那我们就这样:反向边设为inf,这样最小割的时候就不会割到了,判断无解我们直接用 ...
- FJ省队集训DAY3 T1
思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...
- 省队集训 Day3 吴清华
[题目大意] 给网格图,共有$n * n$个关键节点,横向.纵向距离均为$d$,那么网格总长度和宽度均为$(n+1) * d + 1$,最外围一圈除了四角是终止节点.要求每个关键节点都要通过线连向终止 ...
- 省队集训 Day3 陈姚班
[题目大意] 给一张网格图,上往下有流量限制,下往上没有,左往右有流量限制. $n * m \leq 2.5 * 10^6$ [题解] 考场直接上最大流,50分.竟然傻逼没看出狼抓兔子. 平面图转对偶 ...
- JS省队集训记
不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...
- HN2018省队集训
HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...
随机推荐
- 无法打开mfc120.lib
今天在用VS2013编译OSG的时候报错:无法打开mfc120.lib.仔细查了下资料. 我是这么解决的: 安装Multibyte MFC Library for Visual Studio 2013 ...
- Thinkphp5使用validate实现验证功能
作为前端er,对于验证这块有着切身的体会,虽然逐渐得心应手,但始终没有一个内置的功能拿来就能用.tp5恰好提供一个.本文简单介绍并实现以下.主要是实现一下. 验证的实现基于tp5内置的对象valida ...
- 【Docker 命令】- push 命令
docker push : 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库 语法 docker push [OPTIONS] NAME[:TAG] OPTIONS说明: --disable-conte ...
- 整理下本周工作中遇到的疑问;uid/euid/suid;docker镜像管理
1.系统中的父子进程关系,以及docker是如何处理的这种父子进程关系,线上问题发现,子进程长时间得不到退出. 2.调用system系统调用发生了啥事情,发现大量的页表拷贝. 3.通过shell命令通 ...
- [剑指Offer] 66.机器人的运动范围
题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能 ...
- wpf 验证方法
效果图,当放鼠标到文本框上会显示出错的提示.
- .NET中SQL Server数据库连接方法
1. 使用本机上的SQL Server Express 实例上的用户实例. 用户实例的连接创建了一个新的SQL Server 实例.此连接只能是在本地SQL Server 2005实例上并 ...
- Go语言【第五篇】:Go条件语句
Go语言条件 条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为true来决定是否执行指定语句,并在条件为false的情况再执行另外的语句.下图展示了程序语言中条件语句的结构: Go语言提 ...
- CentOS 文本操作命令
1.cat 用于查看纯文本文件,显示行号,加-n参数,适合内容较少的情况 2.more 用于查看纯文本文件,适合内容较多的情况 3.less 用于查看纯文本文件,可以上下翻页 4.head 用于查看纯 ...
- 【刷题】HDU 4405 Aeroplane chess
Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled fr ...