题目大意:

直线上有n个炸弹有坐标x和半径r

当一个炸弹被引爆时 若有炸弹的坐标在该炸弹坐标+-r范围内则另一个炸弹也被引爆

求先引爆每一个炸弹最终会引爆多少炸弹

思路:

可以想到n平方连边然后tarjan缩点跑拓扑

可以通过线段树来优化建图

对每个点向它能直接引爆的左右范围连边

即用线段树中的线段作为点来建图

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<vector>
  8. #include<queue>
  9. #define inf 2139062143
  10. #define ll long long
  11. #define MOD 1000000007
  12. #define MAXN 500100
  13. #define MAXM 10010000
  14. #define V1 g1.to[i]
  15. #define V2 g2.to[i]
  16. using namespace std;
  17. inline ll read()
  18. {
  19. ll x=,f=;char ch=getchar();
  20. while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
  21. while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
  22. return x*f;
  23. }
  24. ll n,m,p[MAXN],rd[MAXN],ans,hsh[MAXN],sl[MAXN<<],sr[MAXN<<],l[MAXN<<],r[MAXN<<];
  25. int dfn[MAXN<<],low[MAXN<<],st[MAXN<<],bl[MAXN<<],stp,top,scc;
  26. int q[MAXN<<],hd=,tl,ind[MAXN<<];
  27. struct graph
  28. {
  29. int cnt,fst[MAXN<<],nxt[MAXM<<],to[MAXM<<],ind[MAXN<<];
  30. graph(){memset(fst,,sizeof(fst));cnt=;}
  31. inline void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,ind[v]++;}
  32. }g1,g2;
  33. void build(int k,int l,int r)
  34. {
  35. sl[k]=l,sr[k]=r;
  36. if(l==r) {hsh[l]=k,m=k;return ;}
  37. int mid=l+r>>;
  38. build(k<<,l,mid);build(k<<|,mid+,r);
  39. g1.add(k,k<<);g1.add(k,k<<|);
  40. }
  41. void mdf(int k,int l,int r,int a,int b,int x)
  42. {
  43. if(l==a&&r==b) {if(l!=r||(l==r&&k!=x)) g1.add(x,k);return ;}
  44. int mid=l+r>>;
  45. if(b<=mid) mdf(k<<,l,mid,a,b,x);
  46. else if(a>mid) mdf(k<<|,mid+,r,a,b,x);
  47. else {mdf(k<<,l,mid,a,mid,x);mdf(k<<|,mid+,r,mid+,b,x);}
  48. }
  49. void tarjan(int x)
  50. {
  51. dfn[x]=low[x]=++stp,st[++top]=x;
  52. for(int i=g1.fst[x];i;i=g1.nxt[i])
  53. if(!dfn[V1]) {tarjan(V1);low[x]=min(low[x],low[V1]);}
  54. else if(!bl[V1]) low[x]=min(low[x],dfn[V1]);
  55. if(low[x]==dfn[x])
  56. {
  57. l[++scc]=inf;int now=;
  58. while(now!=x) now=st[top--],bl[now]=scc,l[scc]=min(l[scc],sl[now]),r[scc]=max(r[scc],sr[now]);
  59. }
  60. }
  61. void build()
  62. {
  63. for(int x=;x<=m;x++)
  64. for(int i=g1.fst[x];i;i=g1.nxt[i])
  65. if(bl[x]!=bl[V1]) g2.add(bl[x],bl[V1]);
  66. }
  67. int main()
  68. {
  69. n=read();build(,,n);int a,b;
  70. for(int i=;i<=n;i++) p[i]=read(),rd[i]=read();
  71. for(int i=;i<=n;i++)
  72. {
  73. a=lower_bound(p+,p+n+,p[i]-rd[i])-p;
  74. b=upper_bound(p+,p+n+,p[i]+rd[i])-p-;
  75. mdf(,,n,a,b,hsh[i]);
  76. }
  77. for(int i=;i<=m;i++) if(!dfn[i]) tarjan(i);
  78. build();for(int i=;i<=scc;i++) if(!g2.ind[i]) q[++tl]=i;
  79. while(hd<=tl)
  80. {
  81. a=q[hd++];
  82. for(int i=g2.fst[a];i;i=g2.nxt[i])
  83. {g2.ind[V2]--;if(!g2.ind[V2]) q[++tl]=V2;}
  84. }
  85. for(int x=tl;x;x--)
  86. for(int i=g2.fst[q[x]];i;i=g2.nxt[i])
  87. l[q[x]]=min(l[q[x]],l[V2]),r[q[x]]=max(r[q[x]],r[V2]);
  88. for(int i=;i<=n;i++) (ans+=(i*(r[bl[hsh[i]]]-l[bl[hsh[i]]]+))%MOD)%=MOD;
  89. printf("%lld\n",ans);
  90. }

bzoj 5017 炸弹的更多相关文章

  1. bzoj 5017 [Snoi2017]炸弹

    题面 https://www.lydsy.com/JudgeOnline/problem.php?id=5017 题解 如果数据范围小一点那么就缩点 然后跑一个基础的DAG上的dp就好了 但是边数是$ ...

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

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

  3. BZOJ 1218: [HNOI2003]激光炸弹(二维前缀和)

    Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n(N<=10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置 ...

  4. BZOJ 1218: [HNOI2003]激光炸弹 前缀DP

    1218: [HNOI2003]激光炸弹 Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n(N<=10000)个目标,用整数Xi,Yi(其值 ...

  5. [BZOJ 1218] [HNOI2003] 激光炸弹 【n logn 做法 - 扫描线 + 线段树】

    题目链接:BZOJ - 1218 题目分析 可以覆盖一个边长为 R 的正方形,但是不能包括边界,所以等价于一个边长为 R - 1 的正方形. 坐标范围 <= 5000 ,直接 n^2 的二维前缀 ...

  6. BZOJ 1218: [HNOI2003]激光炸弹( 前缀和 + 枚举 )

    虽然source写着dp , 而且很明显dp可以搞...但是数据不大 , 前缀和 + 枚举也水的过去..... -------------------------------------------- ...

  7. 【BZOJ】1218: [HNOI2003]激光炸弹(前缀和)

    题目 题目描述 输入输出格式 输入格式: 输入文件名为input.txt 输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi . 输出格式: 输出文件名为 ...

  8. bzoj 1218 [HNOI2003]激光炸弹 二维前缀和

    [HNOI2003]激光炸弹 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3022  Solved: 1382[Submit][Status][Di ...

  9. bzoj 1218: [HNOI2003]激光炸弹

    思路:二维前缀和, 枚举矩形左上端点. #include<bits/stdc++.h> #define LL long long #define fi first #define se s ...

随机推荐

  1. 成为七牛云 Contributor -如何贡献 logkit 代码

    logkit 是 Pandora 开源的一个通用的日志收集工具,可以将不同数据源的数据方便的发送到 Pandora 进行数据分析.除了基本的数据发送功能,logkit 还有容错.并发.监控.删除等功能 ...

  2. BOOST asio 例程daytime不使用库编译方法

    在不使用lib库编译daytime client程序时,按照<Boost程序库完全开发指南>添加的定义 #define BOOST_REGEX_NO_LIB#define BOOST_DA ...

  3. python学习之-- RabbitMQ 消息队列

    记录:异步网络框架:twisted学习参考:www.cnblogs.com/alex3714/articles/5248247.html RabbitMQ 模块 <消息队列> 先说明:py ...

  4. Two Sum(hashtable)

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  5. java代码编译过程

    简单随笔 java程序需要先编译成class文件然后才能执行,由于是编程成立机器代码,虚拟机加载内存的时候更快的执行. java文件编译成class文件步骤如下: 1)词法分析,检查每一个关键字单词是 ...

  6. dtrace-debug

    https://www.objc.io/issues/19-debugging/dtrace/

  7. how to read openstack code: Core plugin and resource extension

    本章我们将写一个自己的core plugin 和一个resource extension来加深理解.(阅读本文的前提是你已经理解了restful以及stevedore等内容) 什么是 core plu ...

  8. GO语言 --socket.io

    socket.io是对websocket的封装以及扩展, 可以跨平台使用, 具体可看官网.. GO语言实现: package main import ( "github.com/googol ...

  9. eclipse中maven插件上传项目jar包到私服

    我们知道,每一个公司都会有自己的工具包或公共包.这样的包就能够上传到公司的maven私服,就不用每一个人都去同步开发包了. 那么,怎么把本地项目打包并公布到私服呢?依照例如以下步骤就能够轻松完毕. 1 ...

  10. curl 发送post请求

    curl 发送post请求 curl -X POST "http://localhost:8080/usr3?id=1&name=3&departmentId=2" ...