题目大意:给你$n$个点,第$i$个点有点权$v_i$。你需要将这$n$个点排成一排,第$i$个点的点权能被累加当且仅当这个点前面存在编号在$[l_i,r_i]$中的点,问你这些点应该如何排列,点权和才能最大。

数据范围:$n≤10^5$,$1≤v_i≤10^4$。

这题状压居然给了70分,场上压根没想正解。

我们不难发现,对于点i,我们连接$l_i→i$,$(l_i+1)→i$,....,$r_i→i$的边,然后跑一个tarjan,缩点后我们得到了一棵树。

对于每棵树,我们显然只需要减去这棵树树根中最小的点权即可。

然后这么做显然是$O(n^2)$的,考虑优化一波

不难发现,这里连边是连向一个区间,我们可以用线段树优化连边,就可以把连边数量降低至log级。

时间复杂度:$O(n\log\ n)$

 #include<bits/stdc++.h>
#define M 400005
using namespace std; struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
int val[M]={},n; int dfn[M]={},low[M]={},b[M]={},d[M]={},sum[M]={},minn[M]={},t=,cnt=; stack<int> s; struct seg{int l,r,id;}a[M<<]={};
int id[M]={},all=;
int build(int x,int l,int r){
a[x].l=l; a[x].r=r;
if(l==r) return a[x].id=id[l]=++all;
int mid=(l+r)>>;
build(x<<,l,mid);
build(x<<|,mid+,r);
}
int build2(int x,int l,int r){
if(l==r) return ;
int mid=(l+r)>>;
build2(x<<,l,mid);
build2(x<<|,mid+,r);
a[x].id=++all;
add(a[x<<].id,a[x].id);
add(a[x<<|].id,a[x].id);
} void updata(int x,int l,int r,int ID){
if(l<=a[x].l&&a[x].r<=r){
add(a[x].id,ID);
return;
}
int mid=(a[x].l+a[x].r)>>;
if(l<=mid) updata(x<<,l,r,ID);
if(mid<r) updata(x<<|,l,r,ID);
} void dfs(int x){
dfn[x]=low[x]=++t; b[x]=; s.push(x);
for(int i=head[x];i;i=e[i].next)
if(!dfn[e[i].u]) dfs(e[i].u),low[x]=min(low[x],low[e[i].u]);
else if(b[e[i].u]) low[x]=min(low[x],dfn[e[i].u]);
if(dfn[x]==low[x]){
int u; cnt++;
do{
u=s.top(); s.pop();
d[u]=cnt; b[u]=;
if(val[u]!=val[]){
sum[cnt]+=val[u]; minn[cnt]=min(minn[cnt],val[u]);
}
}while(u!=x);
}
} int main(){
memset(minn,,sizeof(minn));
memset(val,,sizeof(val));
scanf("%d",&n);
build(,,n);
build2(,,n);
for(int i=;i<=n;i++){
int l,r; scanf("%d%d%d",&l,&r,val+i);
updata(,l,r,id[i]);
}
for(int i=;i<=all;i++) if(!dfn[i]) dfs(i);
for(int x=;x<=all;x++)
for(int i=head[x];i;i=e[i].next)
if(d[e[i].u]!=d[x]) ++b[d[e[i].u]];
int ans=;
for(int i=;i<=cnt;i++){
ans+=sum[i];
if(!b[i]) ans-=minn[i];
}
cout<<ans<<endl;
}

【2019北京集训2】duck 线段树优化建图+tarjan的更多相关文章

  1. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  2. 【2019.7.26 NOIP模拟赛 T3】化学反应(reaction)(线段树优化建图+Tarjan缩点+拓扑排序)

    题意转化 考虑我们对于每一对激活关系建一条有向边,则对于每一个点,其答案就是其所能到达的点数. 于是,这个问题就被我们搬到了图上,成了一个图论题. 优化建图 考虑我们每次需要将一个区间向一个区间连边. ...

  3. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  4. bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...

  5. bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)

    直接建图边数太多,用线段树优化一下 然后缩点,记下来每个点里有多少个炸弹 然后按拓扑序反向dp一下就行了 #include<bits/stdc++.h> #define pa pair&l ...

  6. Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)

    题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...

  7. BZOJ5017 炸弹(线段树优化建图+Tarjan+拓扑)

    Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...

  8. 『炸弹 线段树优化建图 Tarjan』

    炸弹(SNOI2017) Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸 时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi ...

  9. 模拟赛T2 线段树优化建图+tarjan+拓扑排序

    然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会) code: #include <cstdio> #include <string> #include & ...

随机推荐

  1. mac os下 android studio真机调试

    http://www.cnblogs.com/developer-wang/p/6719555.html 如果没有 .bash_profile 只需要创建 .bash_profile,然后增加andr ...

  2. java web 怎么下载大文件(上百M)

    Java代码   ; ]; , )) != -) { , bytesRead); 13.               } 14.               toClient.write(buffer ...

  3. Cacti Install Error

    Cacti Error happened while installing: ERROR: Your MySQL TimeZone database is not populated. Please ...

  4. bzoj5109(图论好题)

    我的参考题解:https://www.cnblogs.com/ccz181078/p/7907022.html: 不过我感觉题解的压位有问题,(1<<x)还不炸上天.不过这题数据水,好像怎 ...

  5. VS SVN

    AnkhSVN - Subversion Support for Visual Studio    直接包管理中就可以安装 VS2015和SVN合作 Visual Studio 添加SVN插件 Ank ...

  6. MySQL5.7的安装配置

    双击进入安装,如下图: 2 点击上图红框“Install MySQL Products”进入安装界面,如下图: 3 根据上图当中第一步骤与第二步骤,进入下图: 4 进入设置界面,如下图: 5 在原来旧 ...

  7. 如何防止ElasticSearch集群出现脑裂现象

    什么是“脑裂”现象? 由于某些节点的失效,部分节点的网络连接会断开,并形成一个与原集群一样名字的集群,这种情况称为集群脑裂(split-brain)现象.这个问题非常危险,因为两个新形成的集群会同时索 ...

  8. hdu 2227

    和之前的hdu3030都快一样了 可以参考之前的题解 #include <iostream> #include <cstdio> #include <cstdlib> ...

  9. 声笔飞码GB2312单字效率分析

    -----------------------声笔飞码强字方式单字效率分析-------------------------- 2   keys: 567       items, 381900209 ...

  10. 火狐浏览器(Firefox)打开EBS form的设置方法

    http://yedward.net/?id=247 客户在使用EBS的时候,很多都是使用IE浏览器打开,但是EBS并不仅仅只是支持IE,对于谷歌浏览器(Chrome).火狐浏览器(Firefox)也 ...