【题目大意】

给出平面上$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 杨北大的更多相关文章

  1. 省队集训Day3 light

    [问题描述] “若是万一琪露诺(俗称 rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她一定也答不上来.” ...

  2. 省队集训Day3 tree

    [题目描述] RHL 有一天看到 lmc 在玩一个游戏. “愚蠢的人类哟,what are you doing”,RHL 说. “我在玩一个游戏.现在这里有一个有 n 个结点的有根树,其中有 m 个叶 ...

  3. bzoj4171 or 省队集训day3 chess: Rhl的游戏

    [题目描述] RHL最近迷上一个小游戏:Flip it.游戏的规则很简单,在一个N*M的格子上,有一些格子是黑色,有一些是白色.每选择一个格子按一次,格子以及周围边相邻的格子都会翻转颜色(边相邻指至少 ...

  4. FJ省队集训DAY3 T2

    思路:如果一个DAG要的路径上只要一条边去切掉,那么要怎么求?很容易就想到最小割,但是如果直接做最小割会走出重复的部分,那我们就这样:反向边设为inf,这样最小割的时候就不会割到了,判断无解我们直接用 ...

  5. FJ省队集训DAY3 T1

    思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...

  6. 省队集训 Day3 吴清华

    [题目大意] 给网格图,共有$n * n$个关键节点,横向.纵向距离均为$d$,那么网格总长度和宽度均为$(n+1) * d + 1$,最外围一圈除了四角是终止节点.要求每个关键节点都要通过线连向终止 ...

  7. 省队集训 Day3 陈姚班

    [题目大意] 给一张网格图,上往下有流量限制,下往上没有,左往右有流量限制. $n * m \leq 2.5 * 10^6$ [题解] 考场直接上最大流,50分.竟然傻逼没看出狼抓兔子. 平面图转对偶 ...

  8. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

  9. HN2018省队集训

    HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...

随机推荐

  1. Where to go from here

    Did you get through all of that content? Congratulations! You've learnt the fundamentals of algorith ...

  2. (七)类、超类和子类 ——(多态,动态绑定,final类,类型转换,抽象类)

    java中所有的继承都是公有继承. 在子类中的构造其内可以初始化超类的公有域,但不能初始化超类的私有域. 因此需要在子类构造前的第一行使用super()语句初始化超类的私有域. 如果超类没有不带参数的 ...

  3. iOS-创建UIScrollerView(封装UIScrollerView)

    创建继承于UIView的类WJImageScrollView,代码实现如下: WJImageScrollView.h #import <UIKit/UIKit.h> /**点击图片bloc ...

  4. Crash使用参考

    整理自man 8 crash 1.简介 Crash工具可以用来分析一个正在运行的内核,也可以用来分析一个内核的crash dump文件,这里说的是内核代码异常产生的crash dump文件,不是应用层 ...

  5. 3dContactPointAnnotationTool开发日志(一)

      周日毕设开题报告结束后浪了一天,今天又要开始回归正轨了.毕设要做一个人和物体的接触点标注工具,听上去好像没啥难度,其实实现起来还是挺麻烦的.   今天没做啥,就弄了个3d场景做样例.把界面搭了一下 ...

  6. 某一线互联网公司前端面试题js部分总结

    js部分 1,使用严格模式的优点 - 消除Javascript语法的一些不合理.不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全之处,保证代码运行的安全: - 提高编译器效率,增加运行速度 ...

  7. 优化mysql的内存

    Mysql占用CPU过高的时候,该从哪些方面下手进行优化? 占用CPU过高,可以做如下考虑:1)一般来讲,排除高并发的因素,还是要找到导致你CPU过高的哪几条在执行的SQL,show processl ...

  8. 《Effective C#》快速笔记(三)- 使用 C# 表达设计

    目录 二十一.限制类型的可见性 二十二.通过定义并实现接口替代继承 二十三.理解接口方法和虚方法的区别 二十四.用委托实现回调 二十五.用事件模式实现通知 二十六.避免返回对内部类对象的引用 二十七. ...

  9. Android基础------Intent组件

    1.什么是intent 同Activity一样,也是Android应用组件在Android中承担着一种指令输出的作用Intent负责对应用中一次操作的动作及动作相关的数据进行描述.Android则根据 ...

  10. Dom样式操作-属性操作

    1. 对样式进行操作: 1) 以样式(C1,C2等)为最小单位进行修改. className, classList, (以列表形式获得) classList.add("C2"), ...