【HDU5861】Road
题意
有n个村庄排成一排,有n-1条路将他们连在一起。每条路开放一天都会花费一定数量的钱。你可以选择打开或者关上任意条路在任意一天,但是每条路只能打开和关闭一次。我们知道m天的运输计划。每天都有一辆马车从村庄ai到存在bi。你需要保证从ai到bi的路在第i天全部打开。如果要使花费最少,每天的花费应该是多少?n,m<=200000。
分析
这个题应该有各种各样的做法吧。
注意到,每条路只能打开和关上一次,我们可以很容易想到一个朴素的算法。
记录下每条路最后一次用到的是哪一天。然后每一天如果需要的路是关闭的就打开它,如果这一天是某条路最后一次用,那么就关闭掉它。
但是呢,暴力肯定是会超时的。我们发现,这n-1条路排成一排,而且每天的运输集合也是连续的一些路。我们把这些看作区间的话,就可以很容易的想到用线段树来维护。
我这个题是用了两个线段树。
第一棵线段树用来维护每一条路最后一次使用是哪一天。
第二棵线段树用来维护当前开着的道路的花费总和。
因为每条路只能打开和关闭一次,所以第二棵线段树的更新不需要打延时标记。
每次查询的结果是当前的sumv[1]
哇这样说好像说不明白哇。直接上代码好了···
对了,我调了很久还是wa,最后发现,输入的时候要判断l,r的顺序,如果l>r的话需要swap(l,r)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <set>
#include <vector> using namespace std;
const int maxn=+;
vector<int>days[maxn];
struct Node{
int l,r;
}a[maxn];
int n,m;
long long w[maxn];
long long sumv[*maxn],numv[*maxn];
int ql,qr;
void update(int o,int L,int R){
if(numv[o]==R-L+)
return;
if(L==R){
sumv[o]=w[L];
numv[o]=;
return;
}
int M=L+(R-L)/;
if(ql<=M)
update(*o,L,M);
if(qr>M)
update(*o+,M+,R);
sumv[o]=sumv[*o]+sumv[*o+];
numv[o]=numv[*o]+numv[*o+];
return;
}
int v;
void update2(int o,int L,int R){
if(L==R){
sumv[o]=;
numv[o]=;
return;
}
int M=L+(R-L)/;
if(v<=M)
update2(*o,L,M);
else
update2(*o+,M+,R);
sumv[o]=sumv[*o]+sumv[*o+];
numv[o]=numv[*o]+numv[*o+];
return;
}
int setv[*maxn];
void update3(int o,int L,int R){
if(ql<=L&&qr>=R){
setv[o]=v;
return;
}
if(setv[o]){
setv[*o]=setv[o];
setv[*o+]=setv[o];
setv[o]=;
}
int M=L+(R-L)/;
if(ql<=M)
update3(*o,L,M);
if(qr>M)
update3(*o+,M+,R);
return;
}
int query(int o,int L,int R){
if(setv[o])return setv[o];
if(L==R)
return ;
int M=L+(R-L)/;
if(v<=M)
return query(*o,L,M);
else
return query(*o+,M+,R);
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=m;i++)days[i].clear();
for(int i=;i<n;i++)
scanf("%lld",&w[i]);
for(int i=;i<=m;i++){
scanf("%d%d",&a[i].l,&a[i].r);
if(a[i].r<a[i].l)
swap(a[i].r,a[i].l); a[i].r--;
}
memset(setv,,sizeof(setv));
memset(sumv,,sizeof(sumv));
memset(numv,,sizeof(numv));
for(int i=;i<=m;i++){
ql=a[i].l,qr=a[i].r,v=i;
update3(,,n-);
}
for(int i=;i<n;i++){
v=i;
int res=query(,,n-);
days[res].push_back(i);
}
for(int i=;i<=m;i++){
ql=a[i].l,qr=a[i].r;
update(,,n-);
printf("%lld\n",sumv[]);
for(int j=;j<days[i].size();j++){
v=days[i][j];
update2(,,n-);
}
}
}
return ;
}
【HDU5861】Road的更多相关文章
- 【BZOJ】【2750】【HAOI2012】Road
最短路+拓扑序DP orz zyf & lyd 统计每条边在多少条最短路径上……其实可以统计 有多少条最短路径经过了x,以及y出发到达任意一个结束点有多少种走法(沿最短路) 我们可以用Dijk ...
- 【CF1016F】Road Projects(贪心)
题意:给你一棵n 个节点的树,定义1到n的代价是1到 n节点间的最短路径的长度. 现在给你 m 组询问,让你添加一条边权为 w 的边(不与原图重复),求代价的最大值.询问之间相互独立. 1≤n,m≤3 ...
- 【POJ3352】Road Construction(边双联通分量)
题意:给一个无向图,问最少添加多少条边后能使整个图变成双连通分量. 思路:双连通分量缩点,缩点后给度为1的分量两两之间连边,要连(ans+1) div 2条 low[u]即为u所在的分量编号,flag ...
- 【CF1252L】Road Construction(基环树,最大流)
题意:给定一张n点n边无重边自环的无向图,刚开始每条边都没有被选择,每条边上有一个颜色集合,必须从中选择一种 有K个工人,每个工人有颜色a[i],需要把工人分配到与其颜色相同的边上 问是否能有一种使得 ...
- 【博弈论】Road to Arabella Gym - 102263B
题目: 题目大意:输入n,k.两个人轮流选一个数x(1<=x<=max(1,n-k))减去n,若到一个人的回合n=0那么那个人失败.Kilani先手. 通过手动模拟几个实例,很容易发现先手 ...
- 【26.83%】【Codeforces Round #380C】Road to Cinema
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【Atcoder】ARC083 D - Restoring Road Network
[算法]图论,最短路? [题意]原图为无向连通图,现给定原图的最短路矩阵,求原图最小边权和,n<=300. [题解]要求最小边权和下,原图的所有边一定是所连两端点的最短路. 那么现在将所有最短路 ...
- 【POJ 3352】 Road Construction
[题目链接] 点击打开链接 [算法] tarjan算法求边双联通分量 [代码] #include <algorithm> #include <bitset> #include ...
- [原]Water Water Union-Find Set & Min-Spanning Tree Problems' Set~Orz【updating...】
[HDU] 1213 - How Many Tables [基础并查集,求父节点个数] 1856 -More is better [基础并查集,注意内存,HDU数据水了,不用离散化,注意路径压缩的方式 ...
随机推荐
- Django之模板(Template)
Django模板系统 官方文档 每一个Web框架都需要一种很便利的方法用于动态生成HTML页面. 最常见的做法是使用模板. 模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插 ...
- 定时框架quartz的一些问题总结
1 什么是Quartz Quartz是OpenSymphony开源组织在Job scheduling领域的开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简单 ...
- bzoj 4465 游戏中的学问
Written with StackEdit. Description 大家应该都见过很多人手拉手围着篝火跳舞的场景吧?一般情况下,大家手 拉手跳舞总是会围成一个大圈,每个人的左手拉着旁边朋友的右手, ...
- opencv之图像阈值化处理
一.函数简介 1.threshold-图像简单阈值化处理 函数原型:threshold(src, thresh, maxval, type, dst=None) src:图像矩阵 thresh:阈值 ...
- vs2015 c++ _findnext 报错
定位 _findnext(hFile,&fileinfo) 报错. 错误 :0x00007FFC70CB0B2D (ntdll.dll)处(位于 Cutton_Dlg.exe 中)引发的异常: ...
- Linux环境抓包命令
有时候有些接口调用问题不好定位或者日志不够详细,那么我们往往会选择通过抓包来看详细的通讯过程.抓包有相关软件,这里说如何直接在环境里抓.假如现在我们在 Linux 下部署了 Tomcat 服务器,端口 ...
- poj1011---DFS
题目的大意是给了你有限个棍子以及每个棍子的长度,而且所有的棍子都是由有限个长度相同的棍子截断得到的,让你求被截棍子的最小长度 搜索剪枝神题,做的我够呛 提供一个比较好的解题报告 http://www ...
- cxGrid使用汇总3
32根据单元的值设置样式 解决:procedure <aForm>.<aColumn>StylesGetContentStyle( Sender: ...
- LVS+Keepalived搭建
LVS+Keepalived搭建 原理说明 (推荐): http://www.cnblogs.com/likehua/archive/2014/06/19/3796849.html http://ou ...
- pmap命令 查看进程用了多少内存
pmap命令 查看进程用了多少内存 用法 pmap [ -x | -d ] [ -q ] pids ...