[SNOI2017]炸弹[线段树优化建图]
线段树优化建图,然后跑一边tarjan把点全部缩起来,炸一次肯定是有连锁反应的所以整个连通块都一样…于是就可以发现有些是只有单向边的不能忘记更新,没了。
#include <bits/stdc++.h>
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
#define rep(i , j , k) for(int i = j ; i <= k ; i ++)
#define Rep(i , j , k) for(int i = j ; i >= k ; i --)
using namespace std ;
using ll = long long ;
using pii = pair <int , int> ;
using vii = vector <int> ;
#define int long long
auto ot = [&]() { cerr << "ATS TXDY" << '\n' ; int ATS_nantf_txdy = true ; } ;
auto _ios = [&]() { ios :: sync_with_stdio(false) ; cin.tie(nullptr) ; cout.tie(nullptr) ; } ;
namespace stO_ATS_Orz {
template < class T > void cmax(T & x , T y) { if(x < y) x = y ; }
template < class T > void cmin(T & x , T y) { if(x > y) x = y ; }
template < class T > void abs(T x) { if(x < 0) x = -x ; }
const int N = 5e5 + 10 ;
const int mod = 1e9 + 7 ;
int n , a[N] , r[N] , id[N] ;
int minl[N << 2] , maxr[N << 2] , sccl[N << 2] , sccr[N << 2] , mx = 0 ;
vii G[N << 2] ;
void build(int l , int r , int p) {
minl[p] = l ; maxr[p] = r ; cmax(mx , p) ;
if(l == r) { id[l] = p ; return ; }
int mid = l + r >> 1 ;
build(l , mid , p << 1) ; build(mid + 1 , r , p << 1 | 1) ;
G[p].push_back(p << 1) ; G[p].push_back(p << 1 | 1) ;
}
void upd(int a , int b , int l , int r , int p , int to) {
if(a <= l && r <= b) { if(p ^ to) G[to].push_back(p) ; return ; }
int mid = l + r >> 1 ;
if(a <= mid) upd(a , b , l , mid , p << 1 , to) ;
if(b > mid) upd(a , b , mid + 1 , r , p << 1 | 1 , to) ;
}
int low[N << 2] , dfn[N << 2] , idx = 0 ;
int col[N << 2] , st[N << 2] , tp = 0 , num = 0 ;
void tarjan(int u) {
low[u] = dfn[u] = ++ idx ; st[++ tp] = u ;
for(int v : G[u]) {
if(! dfn[v]) { tarjan(v) ; cmin(low[u] , low[v]) ; }
else if(! col[v]) { cmin(low[u] , dfn[v]) ; }
}
if(low[u] == dfn[u]) {
++ num ;
do { col[st[tp]] = num ; cmin(sccl[num] , minl[st[tp]]) ; cmax(sccr[num] , maxr[st[tp]]) ; tp -- ; } while(st[tp + 1] ^ u) ;
}
}
vii reG[N << 2] ;
bool vis[N << 2] ;
void dfs(int u) {
vis[u] = 1 ;
for(int v : reG[u]) {
if(vis[v]) { cmin(sccl[u] , sccl[v]) ; cmax(sccr[u] , sccr[v]) ; }
else { dfs(v) ; cmin(sccl[u] , sccl[v]) ; cmax(sccr[u] , sccr[v]) ; }
}
}
void main() {
cin >> n ; build(1 , n , 1) ;
for(int i = 1 ; i <= n ; i ++) { cin >> a[i] >> r[i] ; }
a[n + 1] = 1e18 ; memset(sccl , 0x3f , sizeof(sccl)) ;
for(int i = 1 ; i <= n ; i ++) {
if(! r[i]) { continue ; }
int bg = lower_bound(a + 1 , a + n + 1 , a[i] - r[i]) - a ;
int ed = upper_bound(a + 1 , a + n + 1 , a[i] + r[i]) - a - 1 ;
upd(bg , ed , 1 , n , 1 , id[i]) ; minl[id[i]] = bg ; maxr[id[i]] = ed ;
}
rep(i , 1 , mx) if(! dfn[i]) tarjan(i) ;
rep(i , 1 , mx)
for(int v : G[i])
if(col[i] ^ col[v]) reG[col[i]].push_back(col[v]) ;
memset(vis , 0 , sizeof(vis)) ;
rep(i , 1 , num) if(! vis[i]) dfs(i) ;
int ans = 0 ;
rep(i , 1 , n) ans = (ans + i * (sccr[col[id[i]]] - sccl[col[id[i]]] + 1)) % mod ;
cout << ans << '\n' ;
}
}
signed main() {
_ios() ; ot() ;
return stO_ATS_Orz :: main() , 0 ;
}
[SNOI2017]炸弹[线段树优化建图]的更多相关文章
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...
- bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)
直接建图边数太多,用线段树优化一下 然后缩点,记下来每个点里有多少个炸弹 然后按拓扑序反向dp一下就行了 #include<bits/stdc++.h> #define pa pair&l ...
- 『炸弹 线段树优化建图 Tarjan』
炸弹(SNOI2017) Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸 时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi ...
- BZOJ5017 [Snoi2017]炸弹[线段树优化建边+scc缩点+DAG上DP/线性递推]
方法一: 朴素思路:果断建图,每次二分出一个区间然后要向这个区间每个点连有向边,然后一个环的话是可以互相引爆的,缩点之后就是一个DAG,求每个点出发有多少可达点. 然后注意两个问题: 上述建边显然$n ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- 【ARC069F】Flags 2-sat+线段树优化建图+二分
Description 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input 第一行一个整数 N. 接下来 N 行每行两个整数 xi, ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
随机推荐
- 字节码操作、javassist使用
一.功能 1.动态生成新的类 2.动态改变某个类的结构(添加.删除.修改 新的属性.方法) 二.优势 1.比反射开销小,性能高 2.JAVAasist性能高于反射,低于ASM 使用javassis ...
- gradle与android studio 关系及gradle配置
前言 我们一般开发android 使用android studio ,android studio 安装的时候,会帮我们做两件事,配置好自己的jdk. 实际上,使用的其实不是我们在path中配置的jd ...
- idea websorm 激活码(2020-1-6 实测可用)最新
2019年1月6日用 ZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnR ...
- ES6和node的模块化
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量.CommonJS 和 AMD 模块,都只能在运行时确定这些东西.比如,CommonJS 模块就是对象,输入 ...
- win10下GO的环境配置
目录 问题描述 环境变量配置 问题描述 win10 下配置 GO 语言的运行环境,主要是环境变量的设置 环境变量配置 在windows的PATH变量中添加go的可执行文件所在的目录: PATH=D:\ ...
- pom.xml配置文件详解(Maven)
注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 注:本文转载自:https://blog.csdn.net/u012152619/article/deta ...
- PostgreSQL内核学习笔记十一(索引)
Index Scan涉及到两部分的内容Heap Only Tuple和index-only-scan. 什么是Heap Only Tuple(HOT)? 例如:Update a Row Without ...
- 页面上icon较多,又不想使用臃肿的结构怎么办?
[先看效果图] 例如这种排版,常规有两种情况 1.把[“ & ”]+ 白色背景切一起 2.写结构的时候复杂,例如:div>img*2 +文字标签 读到这里,可能有人说,第一种情况为什么两 ...
- react typescript react-router
typescript 1 connected-react-router
- echarts 【图表的基本使用】
一.柱状图 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...