推箱子

链接:

https://ac.nowcoder.com/acm/contest/176/B

来源:牛客网

题目描述

在平面上有\(n\)个箱子,每个箱子都可以看成一个矩形,两条边都和坐标轴平行。任何两个矩形都不相交,但可能有某个点或某条边重合。约定\(x\)轴正方向为右,\(y\)轴正方向为上。

现在\(\tt{Fizzydavid}\)要推这些箱子。他会选择某个箱子开始,并以每秒\(1\)个单位的速度使这个箱子向右移动。如果路上正面碰上某个箱子,被碰上的箱子会在碰到的那个瞬间开始进入运动状态,以\(1\)个单位的速度向右移动,不会转动或改变运动方向。

准确地说,在某个时刻一个箱子\(i\)处于移动状态当且仅当:\(i\)是选择的箱子,或者存在一个处于移动状态的箱子\(j\),它的右边界等于箱子\(i\)的左边界,且它们在\(y\)轴上的投影的公共长度\(>0\)。你可以发现在这种情况下,任意时刻每个矩形仍然不相交。

\(\tt{Fizzydavid}\)告诉了你所有的信息,需要你求出\(k\)秒后每个矩形的位置。

输入描述:

第一行两个整数\(n\),\(t\)和\(k\)。\(\tt{Fizzydavid}\)开始选择的是输入的第\(t\)个矩形。

接下来\(n\)行每行四个整数\(x_{1,i},y_{1,i},x_{2,i},y_{2,i}\),表示矩形的左下角坐标是\((x_{1,i},y_{1,i})\),右上角坐标是\((x_{2,i},y_{2,i})\)。

输出描述:

输出一行\(n\)个整数,第\(i\)个整数表示\(k秒\)后第\(i\)个矩形的左下角的\(x\)坐标。你可以发现只要知道这个值就能唯一确定矩形的位置。

说明

对于\(30\%\)的数据,\(k\le 100\)。

对于另外\(40\%\)的数据,\(n\le 1000\)。

对于所有的数据,\(n\le 10^5\),\(1\le t\le n\),\(1\le k\le 10^9\),所有坐标都在\(-10^9\)和\(10^9\)之间。保证任意两个矩形不相交。


据说正解是优化连边最短路算法?为什么不试试类似扫描线的算法呢?(考场上线段树数组开小爆\(70\)了

按照矩形的左边界\(x\)坐标为关键字进行排序,从最开始的那个矩形一个一个做过去。

具体的,对矩形在\(y\)轴方向的凸起用线段树维护,每次加入一个矩形的时候查询\(y\)上面区间的最大值,然后看能不能顶到\(\tt{Ta}\)

支持区间赋值和区间最大值就可以了,离散化和动态开点都可以。注意覆盖情况的小细节。


Code:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int N=2e5+10;
  5. struct node
  6. {
  7. int s,t,l,r,id;
  8. bool friend operator <(node n1,node n2){return n1.s<n2.s;}
  9. }mat[N];
  10. int y[N<<1],cnt,n,t,k;
  11. int tag[N<<2],mx[N<<2],ans[N],Time[N];
  12. #define ls id<<1
  13. #define rs id<<1|1
  14. int max(int x,int y){return x>y?x:y;}
  15. void pushdown(int id)
  16. {
  17. if(~tag[id])
  18. {
  19. mx[ls]=mx[rs]=tag[ls]=tag[rs]=tag[id];
  20. tag[id]=-1;
  21. }
  22. }
  23. void change(int id,int L,int R,int l,int r,int d)
  24. {
  25. if(l==L&&r==R)
  26. {
  27. mx[id]=max(mx[id],d);
  28. tag[id]=mx[id];
  29. return;
  30. }
  31. pushdown(id);
  32. int Mid=L+R>>1;
  33. if(r<=Mid) change(ls,L,Mid,l,r,d);
  34. else if(l>Mid) change(rs,Mid+1,R,l,r,d);
  35. else change(ls,L,Mid,l,Mid,d),change(rs,Mid+1,R,Mid+1,r,d);
  36. mx[id]=max(mx[ls],mx[rs]);
  37. }
  38. int query(int id,int L,int R,int l,int r)
  39. {
  40. if(l==L&&r==R) return mx[id];
  41. pushdown(id);
  42. int Mid=L+R>>1;
  43. if(r<=Mid) return query(ls,L,Mid,l,r);
  44. else if(l>Mid) return query(rs,Mid+1,R,l,r);
  45. else return max(query(ls,L,Mid,l,Mid),query(rs,Mid+1,R,Mid+1,r));
  46. }
  47. int main()
  48. {
  49. memset(tag,-1,sizeof(tag));
  50. memset(mx,-1,sizeof(mx));
  51. scanf("%d%d%d",&n,&t,&k);
  52. for(int i=1;i<=n;i++)
  53. {
  54. scanf("%d%d%d%d",&mat[i].s,&mat[i].l,&mat[i].t,&mat[i].r);
  55. --mat[i].r;
  56. y[++cnt]=mat[i].r,y[++cnt]=mat[i].l,mat[i].id=i;
  57. }
  58. std::sort(y+1,y+1+cnt);
  59. cnt=std::unique(y+1,y+1+cnt)-y-1;
  60. for(int i=1;i<=n;i++)
  61. {
  62. mat[i].l=std::lower_bound(y+1,y+1+cnt,mat[i].l)-y;
  63. mat[i].r=std::lower_bound(y+1,y+1+cnt,mat[i].r)-y;
  64. }
  65. std::sort(mat+1,mat+1+n);
  66. for(int i=1;i<=n;i++) if(t==mat[i].id) {t=i;break;}
  67. int d=mat[t].s;
  68. change(1,1,cnt,mat[t].l,mat[t].r,mat[t].t-d);
  69. Time[t]=k;
  70. for(int i=t+1;i<=n;i++)
  71. {
  72. int dis=query(1,1,cnt,mat[i].l,mat[i].r);
  73. if(dis==-1) continue;
  74. if(k>=mat[i].s-(dis+d))
  75. {
  76. k-=mat[i].s-(dis+d);
  77. d+=mat[i].s-(dis+d);
  78. change(1,1,cnt,mat[i].l,mat[i].r,mat[i].t-d);
  79. Time[i]=k;
  80. }
  81. else
  82. break;
  83. }
  84. for(int i=1;i<=n;i++)
  85. ans[mat[i].id]=mat[i].s+Time[i];
  86. for(int i=1;i<=n;i++)
  87. printf("%d ",ans[i]);
  88. return 0;
  89. }

2018.11.4

牛客网 提高组第8周 T2 推箱子 解题报告的更多相关文章

  1. 牛客网 提高组第8周 T1 染色

    染色 链接: https://ac.nowcoder.com/acm/contest/176/A 来源:牛客网 题目描述 \(\tt{fizzydavid}\)和\(\tt{leo}\)有\(n\)个 ...

  2. 18/9/16牛客网提高组Day2

    牛客网提高组Day2 T1 方差 第一眼看就知道要打暴力啊,然而并没有想到去化简式子... 可能因为昨晚没睡好,今天上午困死 导致暴力打了一个半小时,还不对... #include <algor ...

  3. 18/9/9牛客网提高组Day1

    牛客网提高组Day1 T1 中位数 这好像是主席树??听说过,不会啊... 最后只打了个暴力,可能是n2logn? 只过了前30%  qwq #include<algorithm> #in ...

  4. nowcoder(牛客网)提高组模拟赛第四场 解题报告

    T1 动态点分治 就是模拟..... 但是没有过!! 看了题解之后发现.... 坑点:有可能 \(x<=r\),但是

  5. 牛客网提高组模拟赛第七场 T3 洞穴(附bitset介绍)

    就是DP. 我们可以很简单的想到要枚举中间点,进行边数的转移. 但是因为边长数据范围很大,所以我们考虑log的倍增. 状态设计为\(dp[i][j][k]\),为从节点\(i\)走\(2^k\)步能否 ...

  6. 牛客网提高组模拟赛第七场 T2 随机生成树

    其实看懂题就很水啦qwq,就是求\(1-N\)的约数啦. 暴力求的话时间复杂度是\(O(NlogN)\)的,其实正解是枚举每个数的倍数......这样的时间复杂度是\(\frac{N}{1}+\fra ...

  7. 牛客网提高组模拟赛第五场 T1同余方程(异或)(位运算)

    区间不好做,但是我们可以转化成前缀来做.转化为前缀之后之后就是二维前缀和. 但是我还是不怎么会做.所以只能去看吉老师的题解 (确定写的那么简单真的是题解???). 我们要求模一个数余0,就等于找它的倍 ...

  8. nowcoder(牛客网)提高组模拟赛第一场 解题报告

    T1 中位数(二分) 这个题是一个二分(听说是上周atcoder beginner contest的D题???) 我们可以开一个数组b存a,sort然后二分b进行check(从后往前直接遍历check ...

  9. 牛客网提高组第二场---solution

    T1 方差 根据题目要求将式子先写出来注意下面式子中的 $n$ 全部都是 $n-1$$$\begin{aligned}ans&=n^2\times \frac{1}{n}\times \sum ...

随机推荐

  1. 「日常训练」All Friends(POJ-2989)

    题意 分析 代码 #include <iostream> #include <cstring> #include <algorithm> #define MP ma ...

  2. hdu5698瞬间移动(杨辉三角+快速幂+逆元)

    瞬间移动 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  3. FastJson - 从HttpEntity到Json

    在使用java + httpClient施行API自动化时,不可避免地遇到了如下问题: 1. 用Http Response数据做断言: 2. 用上一个请求的Response内容,作为下一个请求的参数: ...

  4. 【springmvc+mybatis项目实战】杰信商贸-2.数据库配置

    首先我们来了解项目的架构 我们分别使用了MySql和Oracle数据库,即是异构数据库.我们做到一个平台支持多个数据库.数据库建模我们使用Sybase公司的PowerDesigner(以后简称PD), ...

  5. [转]Excel数据转化为sql脚本

    在实际项目开发中,有时会遇到客户让我们把大量Excel数据导入数据库的情况.这时我们就可以通过将Excel数据转化为sql脚本来批量导入数据库. 1 在数据前插入一列单元格,用来拼写sql语句. 具体 ...

  6. 【主席树维护mex】 【SG函数递推】 Problem H. Cups and Beans 2017.8.11

    Problem H. Cups and Beans 2017.8.11 原题: There are N cups numbered 0 through N − 1. For each i(1 ≤ i ...

  7. mysql 启动报错

    之前用我这个机器做mysql的测试来,今天启动准备搭建一套线上的主从,结果起不来了... 错误日志: ;InnoDB: End of page dump 170807 11:37:02 InnoDB: ...

  8. 深搜(DFS)与广搜(BFS)区别

    最近做了不少的搜索题,时而用到DFS时而用到BFS,这里对两种搜索方法做一个总结. 广度优先搜索算法(Breadth-First-Search,缩写为 BFS),是一种利用队列实现的搜索算法.简单来说 ...

  9. Swift-assert使用时机

    什么时候使用断言呢? 包含下面的情况时使用断言: 1.整型下标索引作为值传给自定义索引实现的参数时,但下标索引值不能太低也不能太高时,使用断言 2.传值给函数但如果这个传过来的值无效时,函数就不能完成 ...

  10. SpringData——HelloWorld

    1.背景 最开始了解SpringData的时候,以为他不就是ORM的一种实现方式嘛,还能有什么新的东西.从hibernate到ibatis.mybatis,也许他只不过是spring想整合一个更方便的 ...