题意

有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的更多相关文章

  1. 【BZOJ】【2750】【HAOI2012】Road

    最短路+拓扑序DP orz zyf & lyd 统计每条边在多少条最短路径上……其实可以统计 有多少条最短路径经过了x,以及y出发到达任意一个结束点有多少种走法(沿最短路) 我们可以用Dijk ...

  2. 【CF1016F】Road Projects(贪心)

    题意:给你一棵n 个节点的树,定义1到n的代价是1到 n节点间的最短路径的长度. 现在给你 m 组询问,让你添加一条边权为 w 的边(不与原图重复),求代价的最大值.询问之间相互独立. 1≤n,m≤3 ...

  3. 【POJ3352】Road Construction(边双联通分量)

    题意:给一个无向图,问最少添加多少条边后能使整个图变成双连通分量. 思路:双连通分量缩点,缩点后给度为1的分量两两之间连边,要连(ans+1) div 2条 low[u]即为u所在的分量编号,flag ...

  4. 【CF1252L】Road Construction(基环树,最大流)

    题意:给定一张n点n边无重边自环的无向图,刚开始每条边都没有被选择,每条边上有一个颜色集合,必须从中选择一种 有K个工人,每个工人有颜色a[i],需要把工人分配到与其颜色相同的边上 问是否能有一种使得 ...

  5. 【博弈论】Road to Arabella Gym - 102263B

    题目: 题目大意:输入n,k.两个人轮流选一个数x(1<=x<=max(1,n-k))减去n,若到一个人的回合n=0那么那个人失败.Kilani先手. 通过手动模拟几个实例,很容易发现先手 ...

  6. 【26.83%】【Codeforces Round #380C】Road to Cinema

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. 【Atcoder】ARC083 D - Restoring Road Network

    [算法]图论,最短路? [题意]原图为无向连通图,现给定原图的最短路矩阵,求原图最小边权和,n<=300. [题解]要求最小边权和下,原图的所有边一定是所连两端点的最短路. 那么现在将所有最短路 ...

  8. 【POJ 3352】 Road Construction

    [题目链接] 点击打开链接 [算法] tarjan算法求边双联通分量 [代码] #include <algorithm> #include <bitset> #include ...

  9. [原]Water Water Union-Find Set &amp; Min-Spanning Tree Problems&#39; Set~Orz【updating...】

    [HDU] 1213 - How Many Tables [基础并查集,求父节点个数] 1856 -More is better [基础并查集,注意内存,HDU数据水了,不用离散化,注意路径压缩的方式 ...

随机推荐

  1. React Native探索(四)Flexbox布局详解

    相关文章 React Native探索系列 前言 在Android开发中我们有很多种布局,比如LinearLayout和RelativeLayout,同样在React Native也有它的布局,这个布 ...

  2. ng 过滤器

    1.ng中自带的过滤器过滤器:实现对数据的筛选.过滤.格式化. 过滤器是一个有返回值的方法. 过滤器语法:{{ expression |过滤器1:'参数' | 过滤器2:'参数' }} | --> ...

  3. libQt5Core.so: undefined reference to `dlclose@GLIBC_2.4'

    /******************************************************************************** * libQt5Core.so: u ...

  4. 【MFC】MFC技巧学习 当做字典来查

    MFC技巧学习 摘自:http://www.cnblogs.com/leven20061001/archive/2012/10/17/2728023.html 1."属性页的添加:创建对话框 ...

  5. boost 部分编译

    完整编译boost库需要很长时间,而且我们不一定会用到所有的库. 那么如何只编译只需要的库呢? 解压boost源码,进入解压后的目录 ./bootstrap.sh生成bjam ./bjam --bui ...

  6. ActiveMQ面试题

    什么是activemq activeMQ是一种开源的,实现了JMS1.1规范的,面向消息(MOM)的中间件,为应用程序提供高效的.可扩展的.稳定的和安全的企业级消息通信. activemq的作用以及原 ...

  7. initWithImage和imageWithContentsOfFile的区别

    UIImageView *imageView = [[UIImageView alloc] initWithImage:         [UIImage imageNamed:@"icon ...

  8. 洛谷P2835 刻录光盘

    传送门 题目大意:有光盘可以传着看,问最少从哪几个人分发,能全部传一遍. 题解:缩点后求入度为0的点的个数 代码: #include<iostream> #include<cstdi ...

  9. IT售前经验谈

    在IT界,成功的完成一个项目需要销售人员.售前人员.项目实施人员(开发人员).售后服务人员等密切协作.本文从售前技术支持人员的角度,对售前技术支持工作的过程进行了描述,根据作者在售前的经验,提出了各环 ...

  10. ubuntu下使用code::blocks编译运行一个简单的gtk+2.0项目

    在具体的操作之前,首先需要安装一些必要的软件.ubuntu下默认安装了gcc,不过缺少必要的Header file,可以在命令行中输入下面的指令安装build-essential套件:sudo apt ...