题意

有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. VSCode打开文件总是会覆盖上次打开的标签

    在使用VSCode的时候,打开一个文件之后,如果没有修改的话,那么再打开下一个文件的时候,他总会替换上次打开的标签,那么怎么样才能每次都在新的标签打开文件呢? 实际上,这种情况的出现是因为我们点击文件 ...

  2. php打印乘法口诀表

    <?php $n=9; //动态控制乘法口诀表的行数 echo"<table>"; //外层循环控制行数 for($i=1;$i<=$n;$i++){ // ...

  3. Ubuntu+Rmarkdown的中文slides实现(附GitHub template)

    这两天要做毕业论文的答辩slides,搜Rmarkdown中文slides的时候百度到了自己两年前的博客 R+markdown+LaTeX 中文编译解决方案.讲真我一开始还真没有认出来,一看这文风和博 ...

  4. ExpressionTree,Emit,反射

    ExpressionTree,Emit,反射 https://www.cnblogs.com/7tiny/p/9861166.html [前言] 前几日心血来潮想研究着做一个Spring框架,自然地就 ...

  5. Windows编程

    本文整理自百科.知乎与 科学家的世界 问题一:为什么开发windows应用程序不用c 而用.net,java,c++? 用 c+windows API  开发windows 应用程序  比用.net, ...

  6. mysql中修改密码的方式

    参考地址:https://www.cnblogs.com/yang82/p/7794712.html mysql中修改用户密码的方式: 最简单的方法就是借助第三方工具Navicat for MySQL ...

  7. php写入、追加写入文件的实例

    $myfile = fopen("newfile.txt", "w") or die("Unable to open file!"); $t ...

  8. AJAX验证此ID是否有对应的name

    在表格输入一个ID,然后自动根据ID在数据库中查找是否有对应name 这是javascript部分,利用ajax验证 $(document).ready(function() { $("#c ...

  9. window.open()打开新窗口被拦截

    window.open( url )是常用的打开新页面的方法,一般都没有问题,但是如果在ajax回调方法里面使用就会被浏览器拦截,因为在浏览器安全机制中,页面弹窗必须是由用户触发的才是安全弹窗,比如说 ...

  10. mysql数据恢复 insert\update\delete 工具MyFlash

    一.简介MyFlash是由美团点评公司技术工程部开发维护的一个回滚DML操作的工具.该工具通过解析v4版本的binlog,完成回滚操作.相对已有的回滚工具,其增加了更多的过滤选项,让回滚更加容易. 该 ...