Description

在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: 
Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆。 
现在,请你帮忙计算一下,先把第 i 个炸弹引爆,将引爆多少个炸弹呢? 

Input

第一行,一个数字 N,表示炸弹个数。 
第 2∼N+1行,每行 2 个数字,表示 Xi,Ri,保证 Xi 严格递增。 
N≤500000
−10^18≤Xi≤10^18
0≤Ri≤2×10^18

Output

一个数字,表示Sigma(i*炸弹i能引爆的炸弹个数),1<=i<=N mod10^9+7。 

如果一个炸弹能引爆另一个,就对应连一条有向边,询问即为查询每个点能到达的点中最左和最右分别是哪一个。由于边数较多,需要线段树优化建图,然后用tarjan将强连通分量缩点,缩点后在得到的DAG上逆拓扑序递推一下。时间复杂度O(nlogn),空间复杂度O(n)(线段树上的区间连边不需要记录,只要动态计算即可)。

  1. #include<bits/stdc++.h>
  2. typedef long long i64;
  3. const int P=1e9+,N=5e5+;
  4. char buf[N*],*ptr=buf-;
  5. i64 _(){
  6. i64 x=;
  7. int c=*++ptr,f=;
  8. while(c<)c=='-'?f=-:,c=*++ptr;
  9. while(c>)x=x*+c-,c=*++ptr;
  10. return x*f;
  11. }
  12. int n,mx,tk=,ss[<<|],sp=,ans=;
  13. i64 xs[N],rs[N];
  14. void mins(int&a,int b){if(a>b)a=b;}
  15. void maxs(int&a,int b){if(a<b)a=b;}
  16. struct node{
  17. int l,r,dfn,low;
  18. bool in;
  19. void chk0(node&w){
  20. mins(l,w.l),maxs(r,w.r);
  21. }
  22. void chk1(node&w){
  23. mins(low,w.low);
  24. chk0(w);
  25. }
  26. void chk2(node&w){
  27. if(w.in)mins(low,w.dfn);
  28. chk0(w);
  29. }
  30. }ns[<<|];
  31. void tj(int);
  32. void tje(int w,int u){
  33. if(!ns[u].dfn){
  34. tj(u);
  35. ns[w].chk1(ns[u]);
  36. }else ns[w].chk2(ns[u]);
  37. }
  38. void tj(int w){
  39. ns[w].dfn=ns[w].low=++tk;
  40. ns[w].in=;
  41. ss[++sp]=w;
  42. if(!ns[w].l)ns[w].l=n+;
  43. if(w<mx){
  44. tje(w,w<<);
  45. tje(w,w<<^);
  46. }else{
  47. for(int l=mx+ns[w].l-,r=mx+ns[w].r+;r-l>;l>>=,r>>=){
  48. if(~l&)tje(w,l+);
  49. if(r&)tje(w,r-);
  50. }
  51. }
  52. if(ns[w].dfn==ns[w].low){
  53. int u;
  54. do{
  55. ns[u=ss[sp--]].in=;
  56. ns[u].chk0(ns[w]);
  57. }while(u!=w);
  58. }
  59. }
  60. int main(){
  61. fread(buf,,sizeof(buf),stdin);
  62. n=_();
  63. for(int i=;i<=n;++i)xs[i]=_(),rs[i]=_();
  64. for(mx=;mx<=n+;mx<<=);
  65. for(int i=;i<=n;++i){
  66. ns[mx+i].l=std::lower_bound(xs+,xs+n+,xs[i]-rs[i])-xs;
  67. ns[mx+i].r=std::upper_bound(xs+,xs+n+,xs[i]+rs[i])-xs-;
  68. }
  69. tj();
  70. for(int i=;i<=n;++i){
  71. node&w=ns[mx+i];
  72. ans=(ans+i64(i)*(w.r-w.l+))%P;
  73. }
  74. printf("%d\n",ans);
  75. return ;
  76. }

bzoj5017: [Snoi2017]炸弹的更多相关文章

  1. [LOJ#2255][BZOJ5017][Snoi2017]炸弹

    [LOJ#2255][BZOJ5017][Snoi2017]炸弹 试题描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: ...

  2. [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑

    5017: [Snoi2017]炸弹 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 608  Solved: 190[Submit][Status][ ...

  3. BZOJ5017 Snoi2017炸弹(线段树+强连通分量+缩点+传递闭包)

    容易想到每个炸弹向其能引爆的炸弹连边,tarjan缩点后bitset传递闭包.进一步发现每个炸弹能直接引爆的炸弹是一段连续区间,于是线段树优化建图即可让边的数量降至O(nlogn).再冷静一下由于能间 ...

  4. bzoj千题计划311:bzoj5017: [Snoi2017]炸弹(线段树优化tarjan构图)

    https://www.lydsy.com/JudgeOnline/problem.php?id=5017 暴力: 对于每一个炸弹,枚举所有的炸弹,看它爆炸能不能引爆那个炸弹 如果能,由这个炸弹向引爆 ...

  5. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  6. BZOJ5017 [Snoi2017]炸弹[线段树优化建边+scc缩点+DAG上DP/线性递推]

    方法一: 朴素思路:果断建图,每次二分出一个区间然后要向这个区间每个点连有向边,然后一个环的话是可以互相引爆的,缩点之后就是一个DAG,求每个点出发有多少可达点. 然后注意两个问题: 上述建边显然$n ...

  7. bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...

  8. [SNOI2017]炸弹[线段树优化建图]

    [SNOI2017]炸弹 线段树优化建图,然后跑一边tarjan把点全部缩起来,炸一次肯定是有连锁反应的所以整个连通块都一样-于是就可以发现有些是只有单向边的不能忘记更新,没了. #include & ...

  9. BZOJ5017题解SNOI2017炸弹--玄学递推

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5017 分析 老师讲课谈到了这道题,课上想出了个连边建图然后乱搞的操作,被老师钦定的递推方 ...

随机推荐

  1. stringify在苹果电脑下的值不能为空

     sessionStorage.channel = JSON.stringify(  );苹果的safari不接受stringify里面为空 火桑飘零ご 2018/1/25 20:21:49 wind ...

  2. Python--异常处理和断言

    try关键字,定义获取程序错误 except关键字,出现异常错误执行里面的代码 Exception定义错误类,Exception能获取到所有类型的错误错误,as创建错误对象名称,自动获取错误信息 #! ...

  3. inux下C中怎么让才干安全关闭线程

    前言:     多线程程序中,特别是频繁申请.释放线程的情况下,就要注意线程的关闭,最好使用线程池. 一,线程退出方式     (1) 运行完毕后隐式退出:     (2) 由线程本身显示调用pthr ...

  4. Thread与ThreadPool的内存之战

    Thread与ThreadPool使用的时候在内存里对象是如何分布的呢? 今天我们就从内存堆的角度分析下两者. 先上小白鼠代码: static void Main(string[] args)     ...

  5. java程序源码

    //Account.java package pers.liqin.accounlist; public class Account { private String accountID; priva ...

  6. Easy to use cross-platform 3D engines

    C++ http://gamedev.stackexchange.com/questions/21/easy-to-use-cross-platform-3d-engines-for-c-game-d ...

  7. css 如何实现图片等比例缩放

    在进行布局的时候,很多PM都要求图片等比例缩放,而且要求图片不失真,不变形,但是UI设计好了这个div的宽度又不能随意更改,而后台传过来的图片也不是等比例的图片,这就比较难受了,写成 width: 1 ...

  8. 3个问题:MySQL 中 character set 与 collation 的理解;utf8_general_ci 与 utf8_unicode_ci 区别;uft8mb4 默认collation:utf8mb4_0900_ai_ci 的含义

    MySQL 中 character set 与 collation 的理解 出处:https://www.cnblogs.com/EasonJim/p/8128196.html 推荐: 编码使用 uf ...

  9. 创建表时,主键 USING BTREE、USING HASH 的含义(待补充)

    PRIMARY KEY (`id`) USING BTREE

  10. java 加载数据库驱动

    JDBC编程步骤见 JDBC编程步骤 JDBC编程的第一步是加载数据库驱动,使用Class类的forName()方法,Class.forName("com.mysql.jdbc.Driver ...