bzoj 5017 炸弹 线段树优化建图+tarjan+拓扑排序

2023-12-07 04:08

本文主要是介绍bzoj 5017 炸弹 线段树优化建图+tarjan+拓扑排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

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

输入

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

输出

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

样例输入

4
1 1
5 1
6 5
15 15

样例输出

32

题解:

首先应该明确的是这道题一定是用图论知识来做,当一个炸弹i被引爆时,对于能够被当前这颗炸弹i引爆的炸弹j,我们肯定是要建一条i-->j的边,但是由于题目中的边数较多,所以不可能这样建图,那我们可以想到,当一个炸弹被引爆,那么最总一共被引爆的炸弹一定是连续的,所以就有引出区间问题了,那么区间问题我们就可以用线段树来做,当i炸弹能将(ID)【L,R】的炸弹全部引爆时,就建一条pos【i】-->ID的边,那么这样就一定会形成环,因为这颗炸弹处于区间中间,那么久tarjan缩点,然会就是求每个点能够最远到达哪个点,那么要么就dfs(有点慢),有么就top排序,如果是top排序的话,就要反向建图,从最远的点一步一步的推回去,从而解决题目。

总结:充分利用线段树的区间和树形性质,当图论问题转换成区间问题时,我们就可以利用线段树的特性来优化时间和空间。

#include <queue>
#include <cstdio>
#include <algorithm>
#define N 500010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
queue<int> q;
long long a[N] , v[N] , mn[N * 4] , mx[N * 4] , vmin[N * 4] , vmax[N * 4];
int n , pos[N] , head[N * 4] , to[N * 40] , next[N * 40] , cnt;
int deep[N * 4] , low[N * 4] , tot , ins[N * 4] , sta[N * 4] , top , bl[N * 4] , num;
int hh[N * 4] , tt[N * 40] , nn[N * 40] , cc , rd[N * 4];
inline void add(int x , int y)
{to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void build(int l , int r , int x)
{if(l == r){pos[l] = x;return;}int mid = (l + r) >> 1;mn[x] = 1ll << 62 , mx[x] = -1ll << 62;build(lson) , build(rson);add(x , x << 1) , add(x , x << 1 | 1);
}
void update(int b , int e , int p , int l , int r , int x)
{if(b <= l && r <= e){add(p , x);return;}int mid = (l + r) >> 1;if(b <= mid) update(b , e , p , lson);if(e > mid) update(b , e , p , rson);
}
void tarjan(int x)
{int i;deep[x] = low[x] = ++tot , ins[x] = 1 , sta[++top] = x;for(i = head[x] ; i ; i = next[i]){if(!deep[to[i]]) tarjan(to[i]) , low[x] = min(low[x] , low[to[i]]);else if(ins[to[i]]) low[x] = min(low[x] , deep[to[i]]);}if(deep[x] == low[x]){int t;num ++ , vmin[num] = 1ll << 62 , vmax[num] = -1ll << 62;do{t = sta[top -- ] , ins[t] = 0 , bl[t] = num;vmin[num] = min(vmin[num] , mn[t]) , vmax[num] = max(vmax[num] , mx[t]);}while(t != x);}
}
int main()
{int n , i , x;long long ans = 0;scanf("%d" , &n);build(1 , n , 1);for(i = 1 ; i <= n ; i ++ ) scanf("%lld%lld" , &a[i] , &v[i]) , mn[pos[i]] = mx[pos[i]] = a[i];for(i = 1 ; i <= n ; i ++ )update(lower_bound(a + 1 , a + n + 1 , a[i] - v[i]) - a , upper_bound(a + 1 , a + n + 1 , a[i] + v[i]) - a - 1 , pos[i] , 1 , n , 1);for(i = 1 ; i <= n * 4 ; i ++ )if(!deep[i])tarjan(i);for(x = 1 ; x <= n * 4 ; x ++ )for(i = head[x] ; i ; i = next[i])if(bl[x] != bl[to[i]])tt[++cc] = bl[x] , nn[cc] = hh[bl[to[i]]] , hh[bl[to[i]]] = cc , rd[bl[x]] ++ ;for(i = 1 ; i <= num ; i ++ )if(!rd[to[i]])q.push(to[i]);while(!q.empty()){x = q.front() , q.pop();for(i = hh[x] ; i ; i = nn[i]){vmin[tt[i]] = min(vmin[tt[i]] , vmin[x]) , vmax[tt[i]] = max(vmax[tt[i]] , vmax[x]) , rd[tt[i]] -- ;if(!rd[tt[i]]) q.push(tt[i]);}}for(i = 1 ; i <= n ; i ++ )ans = (ans + (long long)(upper_bound(a + 1 , a + n + 1 , vmax[bl[pos[i]]]) - lower_bound(a + 1 , a + n + 1 , vmin[bl[pos[i]]])) * i) % 1000000007;printf("%lld\n" , ans);return 0;
}


这篇关于bzoj 5017 炸弹 线段树优化建图+tarjan+拓扑排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464439

相关文章

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

Python中lambda排序的六种方法

《Python中lambda排序的六种方法》本文主要介绍了Python中使用lambda函数进行排序的六种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1.对单个变量进行排序2. 对多个变量进行排序3. 降序排列4. 单独降序1.对单个变量进行排序

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX