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)(线段树上的区间连边不需要记录,只要动态计算即可)。

#include<bits/stdc++.h>
typedef long long i64;
const int P=1e9+,N=5e5+;
char buf[N*],*ptr=buf-;
i64 _(){
i64 x=;
int c=*++ptr,f=;
while(c<)c=='-'?f=-:,c=*++ptr;
while(c>)x=x*+c-,c=*++ptr;
return x*f;
}
int n,mx,tk=,ss[<<|],sp=,ans=;
i64 xs[N],rs[N];
void mins(int&a,int b){if(a>b)a=b;}
void maxs(int&a,int b){if(a<b)a=b;}
struct node{
int l,r,dfn,low;
bool in;
void chk0(node&w){
mins(l,w.l),maxs(r,w.r);
}
void chk1(node&w){
mins(low,w.low);
chk0(w);
}
void chk2(node&w){
if(w.in)mins(low,w.dfn);
chk0(w);
}
}ns[<<|];
void tj(int);
void tje(int w,int u){
if(!ns[u].dfn){
tj(u);
ns[w].chk1(ns[u]);
}else ns[w].chk2(ns[u]);
}
void tj(int w){
ns[w].dfn=ns[w].low=++tk;
ns[w].in=;
ss[++sp]=w;
if(!ns[w].l)ns[w].l=n+;
if(w<mx){
tje(w,w<<);
tje(w,w<<^);
}else{
for(int l=mx+ns[w].l-,r=mx+ns[w].r+;r-l>;l>>=,r>>=){
if(~l&)tje(w,l+);
if(r&)tje(w,r-);
}
}
if(ns[w].dfn==ns[w].low){
int u;
do{
ns[u=ss[sp--]].in=;
ns[u].chk0(ns[w]);
}while(u!=w);
}
}
int main(){
fread(buf,,sizeof(buf),stdin);
n=_();
for(int i=;i<=n;++i)xs[i]=_(),rs[i]=_();
for(mx=;mx<=n+;mx<<=);
for(int i=;i<=n;++i){
ns[mx+i].l=std::lower_bound(xs+,xs+n+,xs[i]-rs[i])-xs;
ns[mx+i].r=std::upper_bound(xs+,xs+n+,xs[i]+rs[i])-xs-;
}
tj();
for(int i=;i<=n;++i){
node&w=ns[mx+i];
ans=(ans+i64(i)*(w.r-w.l+))%P;
}
printf("%d\n",ans);
return ;
}

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. xdoj1194----(bsgs-用数组实现链表 真的是好啊)

    #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> ...

  2. com.sun.org.apache.xerces.internal.impl.dv.util.Base64出现的问题

    import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; 出现的问题是这个在eclipse中无法使用,解决方法如下: (1)进入ec ...

  3. django 有关session内部函数做法

    session在set和调用时其实分别做了三步: def fileupload(request): request.session['k1'] = 'ppp' ''' .生成一个随机字符串 .set_ ...

  4. 《DSP using MATLAB》Problem 5.17

    1.代码 %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% ...

  5. 《DSP using MATLAB》Problem5.16

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  6. python------模块定义、导入、优化 ------->re模块

    该部分内容引用自:http://www.cnblogs.com/alex3714/articles/5161349.html 谢谢原博主的文章,只是自己学习,无其他使用. re模块 常用正则表达式符号 ...

  7. Go Example--变参函数

    package main import "fmt" func main() { sum(1,2) sum(1,2,3) nums := []int{1,2,3,4} //nums. ...

  8. ios-UITableView无内容时,不显示多余的分隔线

    效果如上. 只要补上以下方法: //设置多于的分割线 -(void)setExtraCellLineHidden: (UITableView *)tableView { UIView *view = ...

  9. Redis源码剖析和注释(七)--- 快速列表(quicklist)

    Redis 快速列表(quicklist)1. 介绍quicklist结构是在redis 3.2版本中新加的数据结构,用在列表的底层实现. 通过列表键查看一下:redis 列表键命令详解 127.0. ...

  10. 日志信息log

    #include<syslog.h> //建立一个到系统日志的连接 //ident参数指向字符串,syslog()输出的每条信息都会包含这个字符串,这个参数的取值通常是程序名 //log_ ...