loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点
loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点
链接
思路
用交错关系建出图来,发现可以直接缩点,拓扑统计。
完了吗,不,瓶颈在于边数太多了,线段树优化建图。
细节
建新图要判重。
内存永远算不对
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+7,mod=1e9+7;
ll read() {
    ll x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,cnt,id[N<<2],ru[N<<2],ans[N<<2];
ll X[500007],R[500007];
int low[N<<2],dfn[N<<2],stak[N<<2],top,vis[N<<2],belong[N<<2],col,siz[N<<2],mmp;
vector<int> G[N<<2];
queue<int> q;
struct node {int v,nxt;}e[N<<4];
int head[N<<2],tot;
void add(int u,int v) {
    e[++tot].v=v;
    e[tot].nxt=head[u];
    head[u]=tot;
}
namespace seg {
    #define ls rt<<1
    #define rs rt<<1|1
    void build(int l,int r,int rt) {
        if(l==r) return id[rt]=l,void();
        int mid=(l+r)>>1;
        id[rt]=++cnt;
        build(l,mid,ls);
        build(mid+1,r,rs);
        add(id[rt],id[ls]);
        add(id[rt],id[rs]);
    }
    void update(int u,int L,int R,int l,int r,int rt) {
        if(L<=l&&r<=R) return add(u,id[rt]),void();
        int mid=(l+r)>>1;
        if(L<=mid) update(u,L,R,l,mid,ls);
        if(R>mid) update(u,L,R,mid+1,r,rs);
    }
}
void tarjan(int u) {
    dfn[u]=low[u]=++mmp;
    vis[u]=1;
    stak[++top]=u;
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        } else if(vis[v]) {
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(low[u]==dfn[u]) {
        ++col;
        while(stak[top]!=u) {
            belong[stak[top]]=col;
            vis[stak[top]]=0;
            if(stak[top]<=n) siz[col]++;
            top--;
        }
        belong[stak[top]]=col;
        vis[stak[top]]=0;
        if(stak[top]<=n) siz[col]++;
        top--;
    }
}
map<pair<int,int> ,int> Hash;
int main() {
    n=cnt=read();
    seg::build(1,n,1);
    for(int i=1;i<=n;++i) X[i]=read()+(ll)3e18,R[i]=read();
    for(int i=1;i<=n;++i) {
        int j=upper_bound(X+i,X+1+n,X[i]+R[i])-X-1;
        if(j!=i) seg::update(i,i+1,j,1,n,1);
        j=lower_bound(X+1,X+i,X[i]-R[i])-X;
        if(j!=i) seg::update(i,j,i-1,1,n,1);
    }
    for(int i=1;i<=cnt;++i)
        if(!dfn[i])
            tarjan(i);
    for(int u=1;u<=cnt;++u) {
        for(int i=head[u];i;i=e[i].nxt) {
            int v=e[i].v;
            if(belong[v]!=belong[u]&&!Hash[make_pair(belong[v],belong[u])]) {
                Hash[make_pair(belong[v],belong[u])]=1;
                G[belong[v]].push_back(belong[u]);
                ru[belong[u]]++;
            }
        }
    }
    for(int i=1;i<=col;++i) {
        if(!ru[i]) {
            q.push(i);
            siz[i]=siz[i];
        }
    }
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        for(auto v:G[u]) {
            siz[v]+=siz[u];
            ru[v]--;
            if(!ru[v]) q.push(v);
        }
    }
    int ans=0;
    for(int i=1;i<=n;++i) {
        ans+=1LL*i*siz[belong[i]]%mod;
        ans%=mod;
    }
    printf("%d\n",ans);
}
loj#2255. 「SNOI2017」炸弹 线段树优化建图,拓扑,缩点的更多相关文章
- loj #2255. 「SNOI2017」炸弹
		#2255. 「SNOI2017」炸弹 题目描述 在一条直线上有 NNN 个炸弹,每个炸弹的坐标是 XiX_iXi,爆炸半径是 RiR_iRi,当一个炸弹爆炸时,如果另一个炸弹所在位置 X ... 
- bzoj5017 [Snoi2017]炸弹   (线段树优化建图+)tarjan 缩点+拓扑排序
		题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ... 
- 【BZOJ4383】[POI2015]Pustynia 线段树优化建图
		[BZOJ4383][POI2015]Pustynia Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r ... 
- AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图
		AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ... 
- bzoj3073: [Pa2011]Journeys 线段树优化建图
		bzoj3073: [Pa2011]Journeys 链接 BZOJ 思路 区间和区间连边.如何线段树优化建图. 和单点连区间类似的,我们新建一个点,区间->新点->区间. 又转化成了单点 ... 
- BZOJ 3073: [Pa2011]Journeys Dijkstra+线段树优化建图
		复习一下线段树优化建图:1.两颗线段树的叶子节点的编号是公用的. 2.每次连边是要建两个虚拟节点 $p1,p2$ 并在 $p1,p2$ 之间连边. #include <bits/stdc++.h ... 
- bzoj4383 [POI2015]Pustynia   拓扑排序+差分约束+线段树优化建图
		题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ... 
- codeforces 787D - Legacy 线段树优化建图,最短路
		题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ... 
- Codeforces 1045A Last chance 网络流,线段树,线段树优化建图
		原文链接https://www.cnblogs.com/zhouzhendong/p/CF1045A.html 题目传送们 - CF1045A 题意 你有 $n$ 个炮,有 $m$ 个敌人,敌人排成一 ... 
随机推荐
- 整理:WPF中XmlDataProvider的用法总结
			原文:整理:WPF中XmlDataProvider的用法总结 一.目的:了解XmlDataProvider中绑定数据的方法 二.绑定方式主要有三种: 1.Xaml资源中内置: <!--XPath ... 
- oracle 根据字段分组取第一条数据及rank函数说明
			当前有这样一个需求,根据外键对子表数据进行分组,取每组中的一条数据就行了,如图: 如:COMMANDID = 26的有两条,只取一条数据. sql语句: select * from(select SY ... 
- Django TypeError: render() got an unexpected keyword argument 'renderer'
			场景: Xadmin添加plugin 来源: 1. xadmin与DjangoUeditor的安装 (第3.3章节) 2. 增加富文本编辑器Ueditor (第14.7章节) 报错: Django T ... 
- Windows定时清理文件处理脚本
			一.运行CMD,输入forfile/?,即可获取forfile的使用方法 /P 路径 /M 文件类型 /D 时间 + | - +:之后 - :之前 example:-2 ... 
- javascript异步编程学习及实例
			所谓异步就是指给定了一串函数调用a,b,c,d,各个函数的执行完结返回过程并不顺序为a->b->c->d(这属于传统的同步编程模式),a,b,c,d调用返回的时机并不确定. 对于js ... 
- 微信小程序调用云函数出错 Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail cloud function service error code -501005, error message Environment not found;
			错误异常: Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail cloud ... 
- 数据结构与算法—Trie树
			Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ... 
- 避免SQL全表模糊查询查询  下载文件时-修改文件名字
			避免SQL全表模糊查询查询 1.模糊查询效率很低: 原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like %...%(全模糊)这样的条件,是无法使用索引的,全表扫描自然效 ... 
- pandas 之 多层索引
			In many applications, data may be spread across a number of files or datasets or be arranged in a fo ... 
- 【转载】深入剖析自定义View之onMeasure
			1.前言 自定义View中我们看到很多都重写了onMeasure方法,那么我们首先得知道onMeasure是做什么的.onMeasure中文意思就是测量,所以它是用于测量View的大小,影响View大 ... 
