题目大意:

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

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

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

思路:

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

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

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

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

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MOD 1000000007
#define MAXN 500100
#define MAXM 10010000
#define V1 g1.to[i]
#define V2 g2.to[i]
using namespace std;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
ll n,m,p[MAXN],rd[MAXN],ans,hsh[MAXN],sl[MAXN<<],sr[MAXN<<],l[MAXN<<],r[MAXN<<];
int dfn[MAXN<<],low[MAXN<<],st[MAXN<<],bl[MAXN<<],stp,top,scc;
int q[MAXN<<],hd=,tl,ind[MAXN<<];
struct graph
{
int cnt,fst[MAXN<<],nxt[MAXM<<],to[MAXM<<],ind[MAXN<<];
graph(){memset(fst,,sizeof(fst));cnt=;}
inline void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,ind[v]++;}
}g1,g2;
void build(int k,int l,int r)
{
sl[k]=l,sr[k]=r;
if(l==r) {hsh[l]=k,m=k;return ;}
int mid=l+r>>;
build(k<<,l,mid);build(k<<|,mid+,r);
g1.add(k,k<<);g1.add(k,k<<|);
}
void mdf(int k,int l,int r,int a,int b,int x)
{
if(l==a&&r==b) {if(l!=r||(l==r&&k!=x)) g1.add(x,k);return ;}
int mid=l+r>>;
if(b<=mid) mdf(k<<,l,mid,a,b,x);
else if(a>mid) mdf(k<<|,mid+,r,a,b,x);
else {mdf(k<<,l,mid,a,mid,x);mdf(k<<|,mid+,r,mid+,b,x);}
}
void tarjan(int x)
{
dfn[x]=low[x]=++stp,st[++top]=x;
for(int i=g1.fst[x];i;i=g1.nxt[i])
if(!dfn[V1]) {tarjan(V1);low[x]=min(low[x],low[V1]);}
else if(!bl[V1]) low[x]=min(low[x],dfn[V1]);
if(low[x]==dfn[x])
{
l[++scc]=inf;int now=;
while(now!=x) now=st[top--],bl[now]=scc,l[scc]=min(l[scc],sl[now]),r[scc]=max(r[scc],sr[now]);
}
}
void build()
{
for(int x=;x<=m;x++)
for(int i=g1.fst[x];i;i=g1.nxt[i])
if(bl[x]!=bl[V1]) g2.add(bl[x],bl[V1]);
}
int main()
{
n=read();build(,,n);int a,b;
for(int i=;i<=n;i++) p[i]=read(),rd[i]=read();
for(int i=;i<=n;i++)
{
a=lower_bound(p+,p+n+,p[i]-rd[i])-p;
b=upper_bound(p+,p+n+,p[i]+rd[i])-p-;
mdf(,,n,a,b,hsh[i]);
}
for(int i=;i<=m;i++) if(!dfn[i]) tarjan(i);
build();for(int i=;i<=scc;i++) if(!g2.ind[i]) q[++tl]=i;
while(hd<=tl)
{
a=q[hd++];
for(int i=g2.fst[a];i;i=g2.nxt[i])
{g2.ind[V2]--;if(!g2.ind[V2]) q[++tl]=V2;}
}
for(int x=tl;x;x--)
for(int i=g2.fst[q[x]];i;i=g2.nxt[i])
l[q[x]]=min(l[q[x]],l[V2]),r[q[x]]=max(r[q[x]],r[V2]);
for(int i=;i<=n;i++) (ans+=(i*(r[bl[hsh[i]]]-l[bl[hsh[i]]]+))%MOD)%=MOD;
printf("%lld\n",ans);
}

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. python和搜索

    # -*- coding: UTF-8 -*- import re # 搜索逻辑 def querylogic(list): query = {} if len(list) > 1 or len ...

  2. vue.js基础知识总结

    初始化一个项目 npm init -y 安装一些依赖 npm install 名称 --save 例如 npm install vue axios bootstrap --save --save 表示 ...

  3. 字符串匹配(codevs 1404)

    题目描述 Description 给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度.给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个.N,M,K<=20000 ...

  4. NodeJS仿WebApi路由

    用过WebApi或Asp.net MVC的都知道微软的路由设计得非常好,十分方便,也十分灵活.虽然个人看来是有的太灵活了,team内的不同开发很容易使用不同的路由方式而显得有点混乱. 不过这不是重点, ...

  5. Codevs 3556 科技庄园==洛谷 P2760

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description Life是codevs的用户,他是一个道德极高的用户,他积极贯彻党的十八大精神, ...

  6. Http、TCP/IP、Socket的区别

    网络由下往上分为 物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层, 三者从本质上来说没有可 ...

  7. ArrayList去除重复元素

    去除一个ArrayList的重复元素有两种方法:(ArrayList与Vector的存储结构是Object[],LinkedList是双向列表) 第一种是不需要借助临时list,用equals方法比较 ...

  8. 转 蓝桥杯 历届试题 大臣的旅费 [ dfs 树的直径 ]

    题解: 求树的直径. 转一篇博客:http://www.cnblogs.com/hanyulcf/archive/2010/10/23/tree_radius.html 树的直径是指树的最长简单路.求 ...

  9. poj2186 求有向图G中所有点都能到达的点的数量

    /*题意:有向图,求这样的点的数量:所有点都能到达它.缩点成有向无环图,思:如果该强连通有出度,那么 从该出度出去的边必然回不来(已经缩点了),所以有出度的强连通必然不是.那么是不是所有出度为0的强连 ...

  10. 推荐10+必备的 WordPress 常用插件

    众多的WordPress插件,使得WordPress的功能得到了较大的扩展,但是也正是由于过多的插件,导致我们很难选择所需的插件.今天,倡萌就根据自己的经验,给WordPress新手推荐一些常用的插件 ...