省队集训 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\)从 ...
随机推荐
- Where to go from here
Did you get through all of that content? Congratulations! You've learnt the fundamentals of algorith ...
- (七)类、超类和子类 ——(多态,动态绑定,final类,类型转换,抽象类)
java中所有的继承都是公有继承. 在子类中的构造其内可以初始化超类的公有域,但不能初始化超类的私有域. 因此需要在子类构造前的第一行使用super()语句初始化超类的私有域. 如果超类没有不带参数的 ...
- iOS-创建UIScrollerView(封装UIScrollerView)
创建继承于UIView的类WJImageScrollView,代码实现如下: WJImageScrollView.h #import <UIKit/UIKit.h> /**点击图片bloc ...
- Crash使用参考
整理自man 8 crash 1.简介 Crash工具可以用来分析一个正在运行的内核,也可以用来分析一个内核的crash dump文件,这里说的是内核代码异常产生的crash dump文件,不是应用层 ...
- 3dContactPointAnnotationTool开发日志(一)
周日毕设开题报告结束后浪了一天,今天又要开始回归正轨了.毕设要做一个人和物体的接触点标注工具,听上去好像没啥难度,其实实现起来还是挺麻烦的. 今天没做啥,就弄了个3d场景做样例.把界面搭了一下 ...
- 某一线互联网公司前端面试题js部分总结
js部分 1,使用严格模式的优点 - 消除Javascript语法的一些不合理.不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全之处,保证代码运行的安全: - 提高编译器效率,增加运行速度 ...
- 优化mysql的内存
Mysql占用CPU过高的时候,该从哪些方面下手进行优化? 占用CPU过高,可以做如下考虑:1)一般来讲,排除高并发的因素,还是要找到导致你CPU过高的哪几条在执行的SQL,show processl ...
- 《Effective C#》快速笔记(三)- 使用 C# 表达设计
目录 二十一.限制类型的可见性 二十二.通过定义并实现接口替代继承 二十三.理解接口方法和虚方法的区别 二十四.用委托实现回调 二十五.用事件模式实现通知 二十六.避免返回对内部类对象的引用 二十七. ...
- Android基础------Intent组件
1.什么是intent 同Activity一样,也是Android应用组件在Android中承担着一种指令输出的作用Intent负责对应用中一次操作的动作及动作相关的数据进行描述.Android则根据 ...
- Dom样式操作-属性操作
1. 对样式进行操作: 1) 以样式(C1,C2等)为最小单位进行修改. className, classList, (以列表形式获得) classList.add("C2"), ...