• 【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)

      

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <set>
      6 #include <vector>
      7 
      8 using namespace std;
      9 const int maxn=200000+10;
     10 vector<int>days[maxn];
     11 struct Node{
     12     int l,r;
     13 }a[maxn];
     14 int n,m;
     15 long long w[maxn];
     16 long long sumv[4*maxn],numv[4*maxn];
     17 int ql,qr;
     18 void update(int o,int L,int R){
     19     if(numv[o]==R-L+1)
     20         return;
     21     if(L==R){
     22         sumv[o]=w[L];
     23         numv[o]=1;
     24         return;
     25     }
     26     int M=L+(R-L)/2;
     27     if(ql<=M)
     28         update(2*o,L,M);
     29     if(qr>M)
     30         update(2*o+1,M+1,R);
     31     sumv[o]=sumv[2*o]+sumv[2*o+1];
     32     numv[o]=numv[2*o]+numv[2*o+1];
     33     return;
     34 }
     35 int v;
     36 void update2(int o,int L,int R){
     37     if(L==R){
     38         sumv[o]=0;
     39         numv[o]=0;
     40         return;
     41     }
     42     int M=L+(R-L)/2;
     43     if(v<=M)
     44          update2(2*o,L,M);
     45     else
     46          update2(2*o+1,M+1,R);
     47     sumv[o]=sumv[2*o]+sumv[2*o+1];
     48     numv[o]=numv[2*o]+numv[2*o+1];
     49     return;
     50 }
     51 int setv[4*maxn];
     52 void update3(int o,int L,int R){
     53     if(ql<=L&&qr>=R){
     54         setv[o]=v;
     55         return;
     56     }
     57     if(setv[o]){
     58       setv[2*o]=setv[o];
     59       setv[2*o+1]=setv[o];
     60       setv[o]=0;
     61     }
     62     int M=L+(R-L)/2;
     63     if(ql<=M)
     64         update3(2*o,L,M);
     65     if(qr>M)
     66         update3(2*o+1,M+1,R);
     67     return;
     68 }
     69 int query(int o,int L,int R){
     70     if(setv[o])return setv[o];
     71     if(L==R)
     72         return 0;
     73     int M=L+(R-L)/2;
     74     if(v<=M)
     75         return query(2*o,L,M);
     76     else
     77         return query(2*o+1,M+1,R);
     78 }
     79 int main(){
     80     while(scanf("%d%d",&n,&m)!=EOF){
     81         for(int i=1;i<=m;i++)days[i].clear();
     82         for(int i=1;i<n;i++)
     83             scanf("%lld",&w[i]);
     84         for(int i=1;i<=m;i++){
     85             scanf("%d%d",&a[i].l,&a[i].r);
     86             if(a[i].r<a[i].l)
     87                 swap(a[i].r,a[i].l);
     88 
     89             a[i].r--;
     90         }
     91         memset(setv,0,sizeof(setv));
     92         memset(sumv,0,sizeof(sumv));
     93         memset(numv,0,sizeof(numv));
     94         for(int i=1;i<=m;i++){
     95             ql=a[i].l,qr=a[i].r,v=i;
     96             update3(1,1,n-1);
     97         }
     98         for(int i=1;i<n;i++){
     99             v=i;
    100             int res=query(1,1,n-1);
    101             days[res].push_back(i);
    102         }
    103         for(int i=1;i<=m;i++){
    104             ql=a[i].l,qr=a[i].r;
    105             update(1,1,n-1);
    106             printf("%lld
    ",sumv[1]);
    107             for(int j=0;j<days[i].size();j++){
    108                     v=days[i][j];
    109                     update2(1,1,n-1);
    110             }
    111         }
    112     }
    113 return 0;
    114 }
    View Code
  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8965561.html
Copyright © 2020-2023  润新知