bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)
直接建图边数太多,用线段树优化一下
然后缩点,记下来每个点里有多少个炸弹
然后按拓扑序反向dp一下就行了
#include<bits/stdc++.h>
#define pa pair<ll,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=5e5+,maxp=maxn*,maxl=maxn*,P=1e9+;
const ll inf=1e18+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N;
ll pos[maxn],r[maxn];
int rg[maxn][],id[maxn],ch[maxp][],pct,root;
int eg[maxl][],egh[maxp],ect;
int eg2[maxl][],egh2[maxp],ect2,ine[maxp];
int dfn[maxp],low[maxp],tot,stk[maxp],sh;
int bel[maxp],nct,hav[maxp],hh[maxp];
int val[maxp],rk[maxp];
bool instk[maxp],islef[maxp],to[maxp];
queue<int> q; inline void adeg(int a,int b){
eg[++ect][]=b;eg[ect][]=egh[a];egh[a]=ect;
}
inline void adeg2(int a,int b){
ine[b]++;
eg2[++ect2][]=b;eg2[ect2][]=egh2[a];egh2[a]=ect2;
} void build(int &p,int l,int r){
p=++pct;
if(l==r) id[l]=p,islef[p]=;
if(l<r){
int m=l+r>>;
build(ch[p][],l,m);
build(ch[p][],m+,r);
adeg(p,ch[p][]),adeg(p,ch[p][]);
}
} void conn(int p,int l,int r,int x,int y,int z){
if(x>y) return;
if(x<=l&&r<=y){
adeg(z,p);
}else{
int m=l+r>>;
if(x<=m) conn(ch[p][],l,m,x,y,z);
if(y>=m+) conn(ch[p][],m+,r,x,y,z);
}
} void tarjan(int x){
dfn[x]=low[x]=++tot;
stk[++sh]=x;instk[x]=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];
if(instk[b]) low[x]=min(low[x],dfn[b]);
else if(!dfn[b]){
tarjan(b);
low[x]=min(low[x],low[b]);
}
}
if(dfn[x]==low[x]){
++nct;
while(sh){
bel[stk[sh]]=nct;
hav[stk[sh]]=hh[nct],hh[nct]=stk[sh];
val[nct]+=islef[stk[sh]];
instk[stk[sh]]=;
sh--;
if(stk[sh+]==x) break;
}
}
} int main(){
//freopen(".in","r",stdin);
int i,j,k;
N=rd();
for(i=;i<=N;i++) pos[i]=rd(),r[i]=rd();
for(i=;i<=N;i++){
rg[i][]=lower_bound(pos+,pos+N+,pos[i]-r[i])-pos;
rg[i][]=upper_bound(pos+,pos+N+,pos[i]+r[i])-pos-;
// printf("%d %d %d\n",i,rg[i][0],rg[i][1]);
}
build(root,,N);
for(i=;i<=N;i++){
conn(root,,N,rg[i][],i-,id[i]);
conn(root,,N,i+,rg[i][],id[i]);
}
for(i=;i<=pct;i++){
if(!dfn[i]) tarjan(i);
}
for(i=;i<=nct;i++){
for(j=hh[i];j;j=hav[j]){
for(k=egh[j];k;k=eg[k][]){
int bb=bel[eg[k][]];if(bb==i) continue;
if(!to[bb]) adeg2(i,bb),to[bb]=;
}
} for(j=hh[i];j;j=hav[j]){
for(k=egh[j];k;k=eg[k][]){
int bb=bel[eg[k][]];
to[bb]=;
}
}
}
int nn=;
for(i=;i<=nct;i++){
if(!ine[i]) q.push(i);
}
while(!q.empty()){
int p=q.front();q.pop();
rk[++nn]=p;
for(i=egh2[p];i;i=eg2[i][]){
int b=eg2[i][];
if(--ine[b]==) q.push(b);
} }
for(i=nct;i;i--){
int p=rk[i];
for(j=egh2[p];j;j=eg2[j][]){
int b=eg2[j][];
val[p]+=val[b];
}
}
ll ans=;
for(i=;i<=N;i++){
ans=(ans+1ll*i*val[bel[id[i]]])%P;
}
printf("%lld\n",ans);
return ;
}
bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)的更多相关文章
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...
- BZOJ5017 炸弹(线段树优化建图+Tarjan+拓扑)
Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...
- 『炸弹 线段树优化建图 Tarjan』
炸弹(SNOI2017) Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸 时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi ...
- Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)
题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...
- 模拟赛T2 线段树优化建图+tarjan+拓扑排序
然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会) code: #include <cstdio> #include <string> #include & ...
- 炸弹:线段树优化建边+tarjan缩点+建反边+跑拓扑
这道题我做了有半个月了...终于A了... 有图为证 一句话题解:二分LR线段树优化建边+tarjan缩点+建反边+跑拓扑统计答案 首先我们根据题意,判断出来要炸弹可以连着炸,就是这个炸弹能炸到的可以 ...
- 【2019.7.26 NOIP模拟赛 T3】化学反应(reaction)(线段树优化建图+Tarjan缩点+拓扑排序)
题意转化 考虑我们对于每一对激活关系建一条有向边,则对于每一个点,其答案就是其所能到达的点数. 于是,这个问题就被我们搬到了图上,成了一个图论题. 优化建图 考虑我们每次需要将一个区间向一个区间连边. ...
随机推荐
- Luogu P3990 [SHOI2013]超级跳马
这道题还是一道比较不可做的矩阵题 首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移: f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2* ...
- Spark在Windows下的环境搭建(转)
原作者:xuweimdm 原文网址:http://blog.csdn.net/u011513853/article/details/52865076 由于Spark是用Scala来写的,所以Spa ...
- SSO单点登录_理解
SSO核心意义就一句话:一处登录,处处登录:一处注销,处处注销.即:在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 很多人容易把SSO与OAuth搞混.这里简单说明一下: OA ...
- Bash笔记
expect写法 /usr/bin/expect <<-EOF set timeout 3000 spawn ssh root@${server_ip} expect { "pa ...
- 由一个“两次请求”引出的Web服务器跨域请求访问问题的解决方案
http://blog.csdn.net/cnhnnyzhy/article/details/53128179 (4)Access-Control-Max-Age 该字段可选,用来指定本次预检请求的有 ...
- 定时备份windows机器上的文件到linux服务器上的操作梳理(rsync)
由于需要对网络设备做备份,备份文件是放到windows机器上的.现在需要将备份数据同步到linux备份机器上,想到的方案有三种: 1)将windows的备份目录共享出来,然后在linux服务器上进行挂 ...
- GCD实现同步方法
在iOS多线程中我们知道NSOperationQueue操作队列可以直接使用addDependency函数设置操作之间的依赖关系实现线程同步,还可以使用setMaxConcurrentOperatio ...
- 基本的排序算法C++实现(插入排序,选择排序,冒泡排序,归并排序,快速排序,最大堆排序,希尔排序)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/8529525.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- VS2013软件的安装和单元测试
VS2013是什么? 微软在Builder 2013开发者大会上发布了Visual Studio 2013预览版,并且发布其程序组件库.NET 4.5.1的预览版.该软件已于北京时间2013年11月1 ...
- 第三个Sprint冲刺第五天(燃尽图)