本题解仅用与作者加深算法理解,也欢迎大家的阅读

做题背景

原本关于二维的点的 \(dp\) 问题一直都没有什么想法,昨天晚上再做一道 \(cdq\) 的题目的时候被同学询问了这道题,发现可以用二维偏序使用的第一关键字排序,第二关键字用数据结构维护的方法来做,今天就把他切了。

题意

你需要从点 \((0,0)\) 走到点 \((n,n)\) ,且只能向右或向上走。同时给你 \(p\) 个点对 \((x_1,y_1),(x_2,y_2)\) ,满足 \(x_1 \leq x_2\) 且 \(y_1 \leq y_2\) 。如果你在中间走到了一个点对的第一个点,你可以立即达到第二点(不计算距离),问你行走的最小距离是多少。

题解

我们联想到用解决二维偏序的方法来做。

我们先根据点对的 \(x_1\) (第一关键词)和 \(y_1\) (第二关键词)来排序,这样的话我们的 \(dp\) 肯定是没有后效性的,然后易得,每一个点对的答案肯定得是从 \(x_1\) 前面的 \(y_2\) 比它小的点转移过来的,同时每个点可以更新的点是满足 \(x_2\) 后面的 \(y_1\) 比他大的点,这个东西是可以用树状数组来维护的。

( \(P.S.\) :\(y_1\) 作为第二关键词是因为会出现一些比较奇怪的点对,比如点对 \((0,0),(0,1)\) 和点对 \((0,2),(0,3)\) ,此时仅根据 \(x_1\) 排序肯定是不行的,可以再加一个第二关键词 \(y_1\) )

然后我们又发现,每一个点更新的顺序并不等于我们排序后的顺序(排序是根据 \(x_1\) ,更新是根据 \(x_2\) ),所以我们可以考虑用一个 \(set\) 来维护一下更新的时间顺序,到了相应的 \(x\) 轴位置再更新相应的点。

然后细节处理好就可以 \(AC\) 了,不要忘记离散化。

以上。

代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. #define IT set<pair<int,int> >::iterator
  5. const int N=1e5+5;
  6. int n,maxn;
  7. struct Board{int x1,y1,x2,y2,data;}s[N];
  8. bool cmp(Board a,Board b)
  9. {
  10. if(a.x1!=b.x1)
  11. return a.x1<b.x1;
  12. return a.y1<b.y2;
  13. };
  14. map<int,int> mpx,mpy;
  15. int ux[N<<1],sizex,uy[N<<1],sizey;
  16. set<pair<int,int> > st;
  17. struct TreeArray
  18. {
  19. int s[N<<1];
  20. int lowbit(int x){return x&(-x);}
  21. void updata(int k,int x){for(;k<(N<<1);k+=lowbit(k))s[k]=min(s[k],x);}
  22. int query(int k){int res=1e18+7;for(;k;k-=lowbit(k))res=min(res,s[k]);return res;}
  23. }t;
  24. signed main()
  25. {
  26. cin>>maxn>>n;;
  27. for(int i=1;i<=n;++i)
  28. {
  29. scanf("%lld%lld%lld%lld",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2);
  30. ux[++sizex]=s[i].x1,ux[++sizex]=s[i].x2;
  31. uy[++sizey]=s[i].y1,uy[++sizey]=s[i].y2;
  32. }
  33. sort(s+1,s+1+n,cmp);
  34. ux[++sizex]=0,ux[++sizex]=maxn;
  35. uy[++sizey]=0,uy[++sizey]=maxn;
  36. sort(ux+1,ux+1+sizex);
  37. sort(uy+1,uy+1+sizey);
  38. sizex=unique(ux+1,ux+1+sizex)-ux-1;
  39. sizey=unique(uy+1,uy+1+sizey)-uy-1;
  40. for(int i=1;i<=sizex;++i) mpx[ux[i]]=i;
  41. for(int i=1;i<=sizey;++i) mpy[uy[i]]=i;
  42. for(int i=1;i<=n;++i)
  43. {
  44. int tmp=mpx[s[i].x1];
  45. for(IT j=st.begin();j!=st.end()&&j->first<=tmp;++j)
  46. t.updata(mpy[s[j->second].y2],s[j->second].data-s[j->second].x2-s[j->second].y2);
  47. while(!st.empty()&&st.begin()->first<=tmp) st.erase(st.begin());
  48. s[i].data=t.query(mpy[s[i].y1])+s[i].x1+s[i].y1;
  49. st.insert(make_pair(mpx[s[i].x2],i));
  50. // printf("%d %d %d\n",s[i].x1,s[i].y1,s[i].data);
  51. }
  52. int tmp=mpx[maxn];
  53. for(IT j=st.begin();j!=st.end()&&j->first<=tmp;++j)
  54. t.updata(mpy[s[j->second].y2],s[j->second].data-s[j->second].x2-s[j->second].y2);
  55. printf("%lld\n",t.query(mpy[maxn])+maxn+maxn);
  56. return 0;
  57. }

P6007 [USACO20JAN]Springboards G的更多相关文章

  1. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  2. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

  3. 题解 P6005 【[USACO20JAN]Time is Mooney G】

    抢第一篇题解 这题的思路其实就是一个非常简单的dijkstra,如果跑到第一个点的数据不能更新的时候就输出 很多人不知道要跑多少次才停.其实这题因为答案要减去 T*c^2,而每条边的值 <= 1 ...

  4. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  5. CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)

    ---恢复内容开始--- CentOS 6.6 升级GCC G++ (当前最新GCC/G++版本为v6.1.0) 没有便捷方式, yum update....   yum install 或者 添加y ...

  6. Linux deepin 下sublimes配置g++ openGL

    参考 :http://blog.csdn.net/u010129448/article/details/47754623 ubuntu 下gnome只要将代码中deepin-terminal改为gno ...

  7. [翻译svg教程]svg 中的g元素

    svg 中的<g>元素用来组织svg元素.如果一组svg元素被g元素包裹了,你可以通过对g元素进行变换(transform),被g元素包裹的元素也将被变换,就好这些被svg包裹的元素是一个 ...

  8. 软件工程:黄金G点小游戏1.0

    我们要做的是黄金G点小游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值. ...

  9. 2016huasacm暑假集训训练五 G - 湫湫系列故事——减肥记I

    题目链接:http://acm.hust.edu.cn/vjudge/contest/126708#problem/G 这是一个01背包的模板题 AC代码: #include<stdio.h&g ...

随机推荐

  1. threading中的其他部分方法

    import threading def wahaha(n): print(n, threading.current_thread()) # 1 <Thread(Thread-1, starte ...

  2. IAR设置字体

    1.IAR设置字体 第一种方法可以在IDE环境下,选择Tools -> option -> Editor - > Colors and Fonts,然后右边的Editor Font就 ...

  3. netsniff使用

    1 netsniff安装与使用 首先直接下载源码包进行部署 安装一些前置包(安装完成的自动忽略) sudo apt install pkg-config sudo apt install libcli ...

  4. Camtasia的标记使用方法

    相信大家都想过学习或者尝试过编辑视频,可能曾经也下载使用过微课录制软件Camtasia(win),或许现在也还在使用.小编现在也经常使用Camtasia录屏编辑视频,在编辑的过程中,总是会不小心在轨道 ...

  5. 在CorelDRAW2019创建对称绘图模式

    对称绘图模式是CorelDRAW 2018推出的全新功能,在2019的版本中又得到了极大的完善,通过对称绘图模式可以创建平衡.和谐.独一无二的效果,对称在大自然中随处可见,因此设计元素很可能将依靠于它 ...

  6. guitar pro系列教程(二):Guitar Pro主界面之记谱功能的详细解析【下】

    本章节我们接着上一章节继续讲解关于guitar pro主界面的记谱功能里的符号功能.有兴趣的朋友可以进来一起学习哦. 首先我们看下图,这是点击按钮便会弹出的一个窗口,进入这个窗口,我们会看到" ...

  7. 使用Sidechain EQ优化FLStudio的贝斯和底鼓

    混音的目标之一是平衡各个声音的音量.当两个声音占据相同的频率范围时,有时就比较难处理.这是贝司和底鼓之间经常会碰到的情况.很多时候我们会使用压缩(compression)来降低他们的音量.  然而,有 ...

  8. 安装git和lsof

    yum install git yum install lsof 查看80端口 lsof -i:80

  9. 简单好用的TCP/UDP高并发性能测试工具

    工具下载地址: 链接:https://pan.baidu.com/s/1fJ6Kz-mfFu_RANrgKqYiyA 提取码:0pyf 最近测试智能设备的远程的性能,思路主要是通过UDP对IP和端口发 ...

  10. IDEA创建web工程,不用Archetype(超简单)

    Idea不用Archetype创建Web项目 以新建模块为例. 新建Maven项目 不勾选[Create from artchetype],直接Next pom中添加一句话: <artifact ...