题目大意:给你$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. PHP-CGI、FASTCGI和php-fpm的关系

    首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. web server(比如说nginx)只是内容的分发者.比如,如果请求/index.h ...

  2. IntelliJ IDEA 2017版 Spring5 java.lang.NoSuchMethodError: org.springframework.boot.SpringApplication.<init>([Ljava/lang/Object;)V

    错误是java.lang.NoSuchMethodError: org.springframework.boot.SpringApplication.<init>([Ljava/lang/ ...

  3. BZOJ 1029 [JSOI2007]建筑抢修 (贪心 + 优先队列)

    1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 5452  Solved: 2422[Submit][Statu ...

  4. java高精度实数和小数

    java 高精度实数和小数 String s = "1231222222222222222222222222222222222222222222222222222222"; Big ...

  5. 公司内部Samba 服务器架设

    1.需求 在公司内部打造一个文件管理系统,其作用域仅仅在公司内部,支持在线对文件的修改和保存操作等,同时也要注意权限问题. 2.策划 目前设立四个群组:运维.开发 .测试和普通,当然所对应的对文件的访 ...

  6. #微码分享#AES算法的C++包装类

    AES为Advanced Encryption Standard的缩写,中文名:高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,用来替代DES.基于std:: ...

  7. rpcbind.service启动失败

    新装的服务器,启动rpcbind.service通常失败,执行下面的两个命令经常卡死,一直不返回,也不报错 #systemctl start nfs-server.service #systemctl ...

  8. chrome用type=file获取图片路径并转base64字符串

    1 html页面 <div class="col-sm-2" style="height: 200px;margin-top: 14px;"> &l ...

  9. centos常用命令--备份

    端口打开 命令如下:/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT #8080为指定端口 /etc/rc.d/init.d/iptables ...

  10. CSS 基础 例子 图片拼合技术

    利用background-position xpos ypos 就是以图片的左上角顶点为原点,往下和右都为正,反之为负,移动图片 如: background-position: 15px 20px;( ...