bzoj 5017 炸弹
题目大意:
直线上有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 炸弹的更多相关文章
- bzoj 5017 [Snoi2017]炸弹
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=5017 题解 如果数据范围小一点那么就缩点 然后跑一个基础的DAG上的dp就好了 但是边数是$ ...
- bzoj千题计划311:bzoj5017: [Snoi2017]炸弹(线段树优化tarjan构图)
https://www.lydsy.com/JudgeOnline/problem.php?id=5017 暴力: 对于每一个炸弹,枚举所有的炸弹,看它爆炸能不能引爆那个炸弹 如果能,由这个炸弹向引爆 ...
- BZOJ 1218: [HNOI2003]激光炸弹(二维前缀和)
Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n(N<=10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置 ...
- BZOJ 1218: [HNOI2003]激光炸弹 前缀DP
1218: [HNOI2003]激光炸弹 Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n(N<=10000)个目标,用整数Xi,Yi(其值 ...
- [BZOJ 1218] [HNOI2003] 激光炸弹 【n logn 做法 - 扫描线 + 线段树】
题目链接:BZOJ - 1218 题目分析 可以覆盖一个边长为 R 的正方形,但是不能包括边界,所以等价于一个边长为 R - 1 的正方形. 坐标范围 <= 5000 ,直接 n^2 的二维前缀 ...
- BZOJ 1218: [HNOI2003]激光炸弹( 前缀和 + 枚举 )
虽然source写着dp , 而且很明显dp可以搞...但是数据不大 , 前缀和 + 枚举也水的过去..... -------------------------------------------- ...
- 【BZOJ】1218: [HNOI2003]激光炸弹(前缀和)
题目 题目描述 输入输出格式 输入格式: 输入文件名为input.txt 输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi . 输出格式: 输出文件名为 ...
- bzoj 1218 [HNOI2003]激光炸弹 二维前缀和
[HNOI2003]激光炸弹 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3022 Solved: 1382[Submit][Status][Di ...
- bzoj 1218: [HNOI2003]激光炸弹
思路:二维前缀和, 枚举矩形左上端点. #include<bits/stdc++.h> #define LL long long #define fi first #define se s ...
随机推荐
- 成为七牛云 Contributor -如何贡献 logkit 代码
logkit 是 Pandora 开源的一个通用的日志收集工具,可以将不同数据源的数据方便的发送到 Pandora 进行数据分析.除了基本的数据发送功能,logkit 还有容错.并发.监控.删除等功能 ...
- BOOST asio 例程daytime不使用库编译方法
在不使用lib库编译daytime client程序时,按照<Boost程序库完全开发指南>添加的定义 #define BOOST_REGEX_NO_LIB#define BOOST_DA ...
- python学习之-- RabbitMQ 消息队列
记录:异步网络框架:twisted学习参考:www.cnblogs.com/alex3714/articles/5248247.html RabbitMQ 模块 <消息队列> 先说明:py ...
- Two Sum(hashtable)
Given an array of integers, find two numbers such that they add up to a specific target number. The ...
- java代码编译过程
简单随笔 java程序需要先编译成class文件然后才能执行,由于是编程成立机器代码,虚拟机加载内存的时候更快的执行. java文件编译成class文件步骤如下: 1)词法分析,检查每一个关键字单词是 ...
- dtrace-debug
https://www.objc.io/issues/19-debugging/dtrace/
- how to read openstack code: Core plugin and resource extension
本章我们将写一个自己的core plugin 和一个resource extension来加深理解.(阅读本文的前提是你已经理解了restful以及stevedore等内容) 什么是 core plu ...
- GO语言 --socket.io
socket.io是对websocket的封装以及扩展, 可以跨平台使用, 具体可看官网.. GO语言实现: package main import ( "github.com/googol ...
- eclipse中maven插件上传项目jar包到私服
我们知道,每一个公司都会有自己的工具包或公共包.这样的包就能够上传到公司的maven私服,就不用每一个人都去同步开发包了. 那么,怎么把本地项目打包并公布到私服呢?依照例如以下步骤就能够轻松完毕. 1 ...
- curl 发送post请求
curl 发送post请求 curl -X POST "http://localhost:8080/usr3?id=1&name=3&departmentId=2" ...