省队集训 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\)从 ...
随机推荐
- LintCode-159.寻找旋转排序数组中的最小值
寻找旋转排序数组中的最小值 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 你可以假设数组中不存在重复的 ...
- .net下将exe改造为既能双击独立运行又能注册为windows服务
最近项目中需要将一些业务的处理程序改造为windows服务,但是考虑到实际需求,也需要能够直接双击运行这些处理程序.首先第一步想到的就是原来的项目不变,只需要在加一个windows服务的项目就行.但是 ...
- java 基础--继承--007
1,子类只能继承父类所有非私有成员 2,子类不能继承父类的构造方法,但可以通过super去访问父类构造方法 3,子类成员变量和父类成员变量名称不一样,如果一样类似于重写,按子类处理,如果一样,就近原则 ...
- 苹果ATS特性服务器配置指南 HTTPS 安卓可以用 IOS 报错。
解决方案:https://www.qcloud.com/document/product/400/6973 ATS检测:https://www.qcloud.com/product/ssl#userD ...
- Java问题排查工具单
前言 平时的工作中经常碰到很多疑难问题的处理,在解决问题的同时,有一些工具起到了相当大的作用,在此书写下来,一是作为笔记,可以让自己后续忘记了可快速翻阅,二是分享,希望看到此文的同学们可以拿出自己日常 ...
- 第25天:js-封装函数-淘宝鼠标展示
封装函数: 1.函数形参相当于变量,不能加引号. 2.实参要和形参一一对应. 案例:鼠标移到小图上,背景展示相应放大的图片.代码如下: <!DOCTYPE html> <html l ...
- 【bzoj4196】[Noi2015]软件包管理器 树链剖分+线段树
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- BZOJ4770 图样(概率期望+动态规划)
考虑求出所有MST的权值和再除以方案数,方案数显然是2mn. 按位考虑,显然应该让MST里的边高位尽量为0.那么根据最高位是0还是1将点集划分成两部分,整张图的MST就是由两部分各自的MST之间连一条 ...
- Django+haystack实现全文搜索出现错误 ImportError: cannot import name signals
原因是在你的settings.py或者其他地方使用了 "import haystack" 当我们使用django-haysatck库时,表面上会有haystack库,但实际上并不 ...
- 【题解】CF#229 E-Gifts
尽管是一道E题,但真心并不很难~不难发现,有一些物品是一定要被选择的,我们所需要决策的仅仅只有那几个有重复价值的物品. 而不同名字之间的概率并不互相影响,所以我们有 \(f[i][j]\) 表示名字为 ...