C103 CDQ 分治+斜率优化+单调栈 P2497 [SDOI2012] 基站建设
视频链接:C103 CDQ 分治+斜率优化+单调栈 P2497 [SDOI2012] 基站建设_哔哩哔哩_bilibili
E51【模板】斜率优化DP 打印文章 - 董晓 - 博客园 (cnblogs.com)
C101【模板】单调栈 P5788 单调栈 - 董晓 - 博客园 (cnblogs.com)
// CDQ分治+斜率优化+单调栈 O(nlogn) #include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define int long long #define mid (l+r>>1) const int N=500005; int n,m,x[N],r[N],v[N],q[N]; double t[N]; //t=1/(2*sqrt(r)) double f[N]; //fi表示第𝑖个点连接前面点的最小代价 struct E{double x,y;}a[N],b[N]; //状态点坐标x,y bool cmpk(E a,E b,E c){ //比较斜率Kab>Kbc return (b.y-a.y)*(c.x-b.x)>(c.y-b.y)*(b.x-a.x); } double getf(int j,int i){ //计算fi return a[j].y+x[i]*a[j].x+v[i]; } void CDQ(int l,int r){ //CDQ分治(归并排序) if(l==r){ a[l].x=t[l],a[l].y=f[l]-x[l]*t[l]; //状态点坐标x,y return; } CDQ(l,mid); //此时左边已按状态坐标x(=t)升序,右边仍按基站坐标xi升序 int top=0; for(int i=l;i<=mid;i++){//用单调栈维护左边状态点的下凸壳 while(top>1&&cmpk(a[q[top-1]],a[q[top]],a[i])) top--; q[++top]=i; } for(int i=mid+1;i<=r;i++){//因斜率-xi会变陡,淘汰劣质点 while(top>1&&getf(q[top-1],i)<getf(q[top],i)) top--; f[i]=min(f[i],getf(q[top],i)); //用栈顶点更新右边答案 } CDQ(mid+1,r); //在后序位置,按状态坐标x归并一下 int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) a[i].x<a[j].x ? b[k++]=a[i++]:b[k++]=a[j++]; while(i<=mid) b[k++]=a[i++]; while(j<=r) b[k++]=a[j++]; for(j=l;j<=r;j++) a[j]=b[j]; } signed main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld%lld%lld",&x[i],&r[i],&v[i]); t[i]=1/(2*sqrt(r[i])); //预处理t } f[1]=v[1]; for(int i=2;i<=n;i++) f[i]=2e18; CDQ(1,n); //CDQ分治 double ans=2e18; for(int i=1;i<=n;i++) if(x[i]+r[i]>=m) ans=min(ans,f[i]); printf("%.3lf\n",ans); }
分类:
C 数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!