Problem B: 专家系统 解题报告
Problem B: 专家系统
Description
一个专家系统是指,你雇佣了\(n\)个专家,他们每个人会做出一个结果,然后你从中选取较多的专家的结果组合而成最终的结果。专家系统广泛应用于传统机器学习领域、决策领域以及老师找学生做出一套试题的答案等等。
现在我们要在平面上找到一个点的坐标\((x, y)\),于是我们雇佣了\(n\)个专家,每个人都会给出一个坐标。为了得出一个较为准确的结果,我们选取其中的\(k\)名专家,他们得出的最小\(x\)坐标记为\(x_{\min}\),最小y坐标记为\(y_{\min}\),最大\(x\)坐标记为\(x_{\max}\),最大\(y\)坐标记为\(y_{\max}\),那么我们有理由相信,最终的这个点坐标一定落在\(x_{\min}\le x\le x_{\max}\), \(y_{\min}\le y\le y_{\max}\)之内。
但是选取不同的\(k\)名专家可能会导致不同的结果。为此,我们定义一个不确定度\(c=\max(x_{\max}-x_{\min},y_{\max}-y_{\min})\)
我们希望选出的\(k\)名专家使得\(c\)值尽可能的小,这样才能比较精确地获取这个点的坐标范围。现在,这个任务交给了你。
简述
现在有\(n\)个坐标\((x_i, y_i)\),你要从中选出\(k\)个。
假设你选出的全部\(k\)个坐标中,\(x\)坐标最小值为\(x_{\min}\),\(x\)坐标最大值为\(x_{\max}\),\(y\)坐标最小值为\(y_{\min}\),\(y\)坐标最大值为\(y_{\max}\)。
那么你得出的不确定度\(c=\max(x_{\max}-x_{\min},y_{\max}-y_{\min})\)
你的目的是让\(c\)尽可能小。
由于可能有很多种选法能够达成这一目的,你只需要输出这个最小的\(c\)即可。
Input
第一行两个正整数\(n,k\), 空格分隔。
接下来\(n\)行,每行\(2\)个整数\(x_i, y_i\),空格分隔,表示一个坐标。
Output
仅一行,一个数,表示最小的\(c\)。
HINT
对于\(20\%\)的数据, \(n\le 50\)。
对于\(40\%\)的数据,\(n\le 300\)。
对于\(60\%\)的数据,\(n\le 2000\)。
对于\(80\%\)的数据,\(n\le 20000\)。
对于\(100\%\)的数据,\(1\le n\le 100000\)。
对于\(100\%\)的数据,\(1\le k\le n\),\(x_i\)和\(y_i\)的绝对值不超过\(2000000000\)
首先吐槽,开2e9的范围..
考试的时候写了个看起来很套路的60分,二分答案然后拿两个指针按\(x\)扫描一下,然后朴素维护一下\(y\),结果因为不明原因爆0,现在都不晓得为啥。
事实上这个题非常的noip,考虑扫描\(x\)区间的时候如何维护\(y\)
每个\(y\)都被选上的时候可以钦定Ta为权值的右端点,设这个权值为\(d\),然后当前二分的值为\(c\),那么所有\(y\)值在\([d-c,d]\)的点都可以被选上。那么我们就可以考虑每个点对其他值域的贡献,其实就是\([d,d+c]\),贡献是个数\(1\)
然后我们可以离散化\(y\)坐标,把这些东西放在线段树里面,就是维护一个区间加和最大值就可以了。
Code:
#include <cstdio>
#include <algorithm>
const int N=1e5+10;
#define ll long long
const ll inf=(1ll<<40);
struct node
{
ll x,y;
bool friend operator <(node a,node b){return a.x<b.x;}
}dx[N];
int mx[N<<2],tag[N<<2];
using std::max;
#define ls id<<1
#define rs id<<1|1
void build(int id,int l,int r)
{
mx[id]=tag[id]=0;
int mid=l+r>>1;
if(l^r) build(ls,l,mid),build(rs,mid+1,r);
}
void pushdown(int id)
{
if(tag[id])
{
tag[ls]+=tag[id],tag[rs]+=tag[id];
mx[ls]+=tag[id],mx[rs]+=tag[id];
tag[id]=0;
}
}
void change(int id,int L,int R,int l,int r,int d)
{
if(l==L&&r==R)
{
tag[id]+=d,mx[id]+=d;
return;
}
pushdown(id);
int Mid=L+R>>1;
if(r<=Mid) change(ls,L,Mid,l,r,d);
else if(l>Mid) change(rs,Mid+1,R,l,r,d);
else change(ls,L,Mid,l,Mid,d),change(rs,Mid+1,R,Mid+1,r,d);
mx[id]=max(mx[ls],mx[rs]);
}
int n,m,k;ll dy[N];
bool check(ll d)
{
build(1,1,m);
int l=1,r=1,p;
p=std::upper_bound(dy+1,dy+1+m,dy[dx[l].y]+d)-dy-1;
change(1,1,m,dx[l].y,p,1);
while(r<n&&dx[r+1].x-dx[l].x<=d)
{
++r;
p=std::upper_bound(dy+1,dy+1+m,dy[dx[r].y]+d)-dy-1;
change(1,1,m,dx[r].y,p,1);
}
if(mx[1]>=k) return true;
while(r<n)
{
++r;
while(dx[r].x-dx[l].x>d)
{
p=std::upper_bound(dy+1,dy+1+m,dy[dx[l].y]+d)-dy-1;
change(1,1,m,dx[l++].y,p,-1);
}
p=std::upper_bound(dy+1,dy+1+m,dy[dx[r].y]+d)-dy-1;
change(1,1,m,dx[r].y,p,1);
if(mx[1]>=k) return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld%lld",&dx[i].x,&dx[i].y),dy[i]=dx[i].y;
std::sort(dx+1,dx+1+n);
std::sort(dy+1,dy+1+n);
m=std::unique(dy+1,dy+1+n)-dy-1;
for(int i=1;i<=n;i++) dx[i].y=std::lower_bound(dy+1,dy+1+m,dx[i].y)-dy;
ll l=1,r=4000000000ll;
while(l<r)
{
ll mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%lld\n",l);
return 0;
}
2018.12.31
Problem B: 专家系统 解题报告的更多相关文章
- ZOJ Problem Set - 1025解题报告
ZOJ Problem Set - 1025 题目分类:基础题 原题地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=10 ...
- ACM: A Simple Problem with Integers 解题报告-线段树
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%lld & %l ...
- BestCoder18 1002.Math Problem(hdu 5105) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5105 题目意思:给出一个6个实数:a, b, c, d, l, r.通过在[l, r]中取数 x,使得 ...
- Problem - 433C - Codeforces解题报告
对于这题本人刚开始的时候的想法是:先把最大两数差的位置找到然后merge计算一个值再与一连串相同的数做merge后计算一个值比较取最大值输出:可提交后发现不对,于是本人就搜了一下正解发现原来这题的正确 ...
- Problem A: 选举 解题报告
Problem A: 选举 题意 给出一个投票过程.有\(n\)个选民和\(m\)个候选人,每个选民\(i\)有个不重且有序的可投集合\(\{a_i\}\). 对于第一轮投票,选民\(i\)会投给\( ...
- Problem A: 种树 解题报告
Problem A: 种树 Description 很久很久以前,一个蒟蒻种了一棵会提问的树,树有\(n\)个节点,每个节点有一个权值,现在树给出\(m\)组询问,每次询问两个值:树上一组点对\((x ...
- Problem C: 多线程 解题报告
Problem C: 多线程 Description 多线程是一种常见的加速手段,利用多个线程同时处理不同的任务可以一定程度上减少总耗时,达到提高效率的目的.然而,多个线程间的执行顺序是完全不可控的, ...
- Problem A: 踢罐子 解题报告
Problem A: 踢罐子 Description 平面上有\(n\)个点,其中任意2点不重合,任意3点不共线. 我们等概率地选取一个点A,再在剩下的\(n-1\)个点中等概率地选取一个点B,再在剩 ...
- Problem C Dist 解题报告
Problem C Dist Description 有一个\(n\)个点带边权的连通无向图,边集用\(k\)个集合\(s_1,s_2,\dots,s_k\)和\(k\)个整数\(w_1,w_2,\d ...
随机推荐
- XSS Challenges练习及解答
一个偶然的机会在知道创宇的技能表里看到了一个练习XSS的网站http://xss-quiz.int21h.jp,正好想研究这个,于是试着做了一下. 第一.二题是最简单的,直接在搜索框中输入以下代码就成 ...
- 20155304《网络对抗》Exp2 后门原理与实践
20155332<网络对抗>Exp2 后门原理与实践 实验内容 (3.5分) (1)使用netcat获取主机操作Shell,cron启动 (0.5分) (2)使用socat获取主机操作Sh ...
- Jmeter 安装后无法启动问题
问题:按照教程java环境安装完成,也下载了 Jmeter 安装包,但是在启动的时候 dos窗口就一直提示下面的错误信息 ‘findstr' 不是内部或外部命令,也不是可运行的程序或批处理文件. ...
- Vue 使用细节收集
JSX 中 on 开头的属性名 在用 elementui 中的 el-upload 的时候,他们组件中有一个属性 on-change ,也不知道谁想出来的属性名,太扯淡了,非要 on 开头,我开始的代 ...
- POJ 2965&&1753
最近由于复习备考(然而考得还是很炸),很久没打题目了.现在开始刷寒假作业,不得不搞POJ 话说没有中文真的好烦啊! 先看1753 题目大意是说在一个4*4的格子中有黑白两色的棋子,你可以翻动其中的棋子 ...
- java之平台无关
java虚拟机是执行字节码文件(.class)的虚拟机进程. java源程序(.java)被编译器编译成------>字节码文件(.class),然后字节码文件,将由java虚拟机,解释成--- ...
- Linux中tty、pty、pts的概念区别 转载
基本概念: > tty(终端设备的统称): tty一词源于Teletypes,或teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,后来这东西 ...
- oracle移动数据/修改数据文件路径
参考:http://wwyz998.blog.163.com/blog/static/321867852011117111832334/ oracle移动数据文件 1.连接到数据库 [oracle@l ...
- 生成本地测试用https证书,支持通配符和多域名,初学OpenSSL
18-01-26在v2ex上看到一妹纸发的<身为一个 21 岁的年轻程序员,我已经腰突了(躺>,哈哈,感同身受,想到这几天我左腿麻木持续了好几天,前几天屁股疼的只要坐下就站不起来,不过站着 ...
- nginx反向代理设置自定义错误页面
为nginx反向代理设置自定义错误页面 转:https://blog.csdn.net/u014433030/article/details/77507839 如果我们的nginx配置了反向代理,如下 ...