2015.6.24 XJOI T1.不可视境界线
来源:互联网 发布:网站推广工作是seo吗 编辑:程序博客网 时间:2024/05/16 09:06
背景:
题目描述:
输入格式:
输出格式:
样例输入:
41 02 03 04 0
样例输出:
2.0000
数据范围:
时间限制:
1s
空间限制:
512MB
考试的时候只想到了cdq分治...没想到b的处理方法所以写了40分的结果拼上去的暴力挂了只剩下3 4的20分了
其实这题cdq分治的确可做
首先题目那个-a是忽悠你的。可以直接去掉
那么转移方程就是f[i]=min(f[i],sqrt(f[j]*f[j]+(a[i]-a[j])*(a[i]-a[j]))
我们把a[i]降序排序
然后移项后如果j>k j比k对于i优的话,那么满足((f[j]*f[j]+a[j]*a[j])+(f[k]*f[k]+a[k]*a[k]))/(2*(a[j]-a[k]))>a[i]
我们cdq分治处理左右区间。保证转移右区间的时候左区间已经转移完毕
然后左区间按照a降序,右区间按照b降序
这样就可以在枚举到右区间某个数的时候把可行左区间加入队列
然后对已经加入左区间的斜率二分就可以了
#include<cmath>#include<queue>#include<cstdio>#include<algorithm>using namespace std;struct enemy{ double a,b; double f; int p;}x[100001],tx[100001];int n;double f[100001];int q[100001];inline bool cmp1(enemy x,enemy y){ return x.b>y.b;}inline bool cmp2(enemy x,enemy y){ return x.a<y.a;}inline double getk(int j,int k){ if(j==0&&k==0) return -1; return ((x[j].f*x[j].f+x[j].a*x[j].a)-(x[k].f*x[k].f+x[k].a*x[k].a))/(double(2)*(x[j].a-x[k].a));}inline void cdq(int ll,int rr){ if(ll!=rr) { int mid=(ll+rr)/2; int i; int p1=ll-1,p2=mid; for(i=ll;i<=rr;i++) { if(x[i].p<=mid) { p1++; tx[p1]=x[i]; } else { p2++; tx[p2]=x[i]; } } for(i=ll;i<=rr;i++) x[i]=tx[i]; cdq(ll,mid); sort(x+mid+1,x+rr+1,cmp1); int r=0; int pp=ll; for(i=mid+1;i<=rr;i++) { while(x[pp].a>=x[i].b&&pp<=mid) { while(1<r&&getk(q[r],q[r-1])<getk(pp,q[r])) r--; r++; q[r]=pp; pp++; } int l0=2,r0=r; while(l0<=r0) { int mid=(l0+r0)/2; if(getk(q[mid],q[mid-1])>=x[i].a) l0=mid+1; else r0=mid-1; } if(r0!=0) x[i].f=min(x[i].f,sqrt(x[q[r0]].f*x[q[r0]].f+(x[q[r0]].a-x[i].a)*(x[q[r0]].a-x[i].a))); } cdq(mid+1,rr); p1=ll; p2=mid+1; int p=ll-1; while(p1<=mid&&p2<=rr) { if(x[p1].a>x[p2].a) { p++; tx[p]=x[p1]; p1++; } else { p++; tx[p]=x[p2]; p2++; } } while(p1<=mid) { p++; tx[p]=x[p1]; p1++; } while(p2<=rr) { p++; tx[p]=x[p2]; p2++; } for(i=ll;i<=rr;i++) x[i]=tx[i]; }}inline void solve2(){ cdq(1,n); int i; for(i=1;i<=n;i++) if(x[i].p==n) break; printf("%.4lf\n",x[i].f);}int main(){ scanf("%d",&n); int i; bool flag=true; for(i=1;i<=n;i++) { scanf("%lf%lf",&x[i].a,&x[i].b); x[i].p=i; if(x[i].b==0) x[i].f=x[i].a; else x[i].f=1000000000; if(x[i].b!=0) flag=false; } solve2(); return 0;}
0 0
- 2015.6.24 XJOI T1.不可视境界线
- XJOI #8T1 炮兵阵地 状压DP
- 【XJOI】NOIP2016提高组冲剌题1 T1 挖金矿
- XJOI NOIP2016提高组冲剌题1 T1:挖金矿(二分答案)
- 索引的不可视
- 不可视索引
- XJOI NOIP16提高组赛前训练17 T1:GotoAndPlay(二分图染色)
- XJOI NOIP16提高组赛前训练18-day2 T1:友好数对(数论)
- T1
- T1
- t1
- t1
- t1
- t1
- t1
- T1
- T1
- XJOI 公交线路
- js 变量 函数名的提升
- 《Orange'S:一个操作系统的实现》学习笔记---开发环境搭建
- 正确的解决GridLayout在安卓4.0以下版本中兼容问题
- LeetCode Multiply Strings
- php的入门第一个例子(包括linux的环境安装与包括页面跳转,以及curl命令的调用)
- 2015.6.24 XJOI T1.不可视境界线
- MacBook 连接Centos服务器
- Linux虚拟机与外面系统ping不通,或者连不上网
- 各种排序算法的分析及java实现
- LNMP基础配置及说明
- POJ3253
- 多线程编程(二)--进程&&线程
- Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
- java进阶 ------ Java NIO