• HDU 5861 Road


    题目:Road

    链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5861

    题意:有n 个村庄在一条公路上,每两个村庄之间的路有使用和不使用两种状态,使用时,每天需耗费wi 元,每段路初始时都是不使用的,在m 天中,我们总共可以打开一次、关闭一次,从第一天到第m 天,每一天给出ai、bi,表示ai 到bi 之间的路必须是通的,问每一天n-1段路的总耗费最小为多少。

    思路:

      每段路只能打开一次,关闭一次,我们可以求出第i 段路最早什么时候使用t1,最晚什么时候使用t2,那么我们就可以在天数t1 打开它,t2+1关闭它。

      离线+线段树可以处理出每一段路的参数t1、t2。比如第i 天要使用ai 到bi,那么ai 到bi 赋值i ,维护最大值和最小值即可。

      接下来可以用vector<int> v[N];来保存第i 天要打开哪些路,再用一个保存第i 天关闭哪些路。打开路i 就是点i 赋值wi,关闭就是赋值0。

      遍历m 天,对于每一天,进行完打开和关闭操作后,输出总和就好。

    AC代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<math.h>
      5 #include<set>
      6 #include<map>
      7 #include<list>
      8 #include<stack>
      9 #include<queue>
     10 #include<vector>
     11 #include<string>
     12 #include<algorithm>
     13 using namespace std;
     14 #define lson rt<<1
     15 #define rson rt<<1|1
     16 #define N 200020
     17 #define M 100010
     18 #define Mod 1000000007
     19 #define LL long long
     20 #define INF 0x7fffffff
     21 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
     22 #define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
     23 #define MEM(x,i) memset(x,i,sizeof(x))
     24 
     25 struct Node
     26 {
     27   int Max;
     28   int Min;
     29   int w;
     30   int l,r;
     31   int mid()
     32   {
     33     return (l+r)/2;
     34   }
     35 };
     36 Node v[N<<2];
     37 void build(int l,int r,int rt)
     38 {
     39   v[rt].Min=INF;
     40   v[rt].Max=0;
     41   v[rt].w=0;
     42   v[rt].l=l;
     43   v[rt].r=r;
     44   if(l==r-1) return ;
     45   build(l,v[rt].mid(),lson);
     46   build(v[rt].mid(),r,rson);
     47 }
     48 void push_day(int rt)
     49 {
     50   if(v[rt].Min!=INF)
     51   {
     52     v[lson].Min=min(v[lson].Min,v[rt].Min);
     53     v[rson].Min=min(v[rson].Min,v[rt].Min);
     54     v[rt].Min=INF;
     55   }
     56   if(v[rt].Max!=0)
     57   {
     58     v[lson].Max=max(v[lson].Max,v[rt].Max);
     59     v[rson].Max=max(v[rson].Max,v[rt].Max);
     60     v[rt].Max=0;
     61   }
     62 }
     63 void update_day(int l,int r,int g,int rt)
     64 {
     65   if(v[rt].l==l && v[rt].r==r)
     66   {
     67     v[rt].Max=max(v[rt].Max,g);
     68     v[rt].Min=min(v[rt].Min,g);
     69     return ;
     70   }
     71   push_day(rt);
     72 
     73   int mid=v[rt].mid();
     74   if(l>=mid) update_day(l,r,g,rson);
     75   else if(r<=mid) update_day(l,r,g,lson);
     76   else
     77   {
     78     update_day(l,mid,g,lson);
     79     update_day(mid,r,g,rson);
     80   }
     81 }
     82 void look_day(int x,int &Max,int &Min,int rt)
     83 {
     84   if(v[rt].l==v[rt].r-1)
     85   {
     86     Max=v[rt].Max+1;
     87     Min=v[rt].Min;
     88     return ;
     89   }
     90   push_day(rt);
     91   int mid=v[rt].mid();
     92   if(x<mid) look_day(x,Max,Min,lson);
     93   else if(x>=mid) look_day(x,Max,Min,rson);
     94 }
     95 vector<int> vv[N];
     96 vector<int> u[N];
     97 int w[N];
     98 void up(int rt)
     99 {
    100   v[rt].w=v[lson].w+v[rson].w;
    101 }
    102 void update(int x,int w,int rt)
    103 {
    104   if(v[rt].l==v[rt].r-1)
    105   {
    106     v[rt].w=w;
    107     return ;
    108   }
    109   int mid=v[rt].mid();
    110   if(x<mid) update(x,w,lson);
    111   else if(x>=mid) update(x,w,rson);
    112   up(rt);
    113 }
    114 void update(int x,int rt)
    115 {
    116   if(v[rt].l==v[rt].r-1)
    117   {
    118     v[rt].w=0;
    119     return ;
    120   }
    121   int mid=v[rt].mid();
    122   if(x<mid) update(x,lson);
    123   else if(x>=mid) update(x,rson);
    124   up(rt);
    125 }
    126 int main()
    127 {
    128   int n,m,x,y;
    129   while(scanf("%d%d",&n,&m)!=EOF)
    130   {
    131     build(1,n,1);
    132 
    133     FOR(i,1,n-1){
    134       scanf("%d",&w[i]);
    135     }
    136     FOR(i,1,m){
    137       scanf("%d%d",&x,&y);
    138       if(x>y) x^=y^=x^=y;
    139       update_day(x,y,i,1);
    140     }
    141     FOR(i,1,n-1){
    142       int Max,Min;
    143       look_day(i,Max,Min,1);
    144       if(Min!=INF) vv[Min].push_back(i);
    145       if(Max!=0) u[Max].push_back(i);
    146     }
    147 
    148     FOR(i,1,m){
    149       for(int j=0;j<vv[i].size();j++){
    150         update(vv[i][j],w[vv[i][j] ],1);
    151       }
    152       for(int j=0;j<u[i].size();j++){
    153         update(u[i][j],1);
    154       }
    155       printf("%d
    ",v[1].w);
    156     }
    157     FOR(i,1,m+1)
    158     {
    159       vv[i].clear();
    160       u[i].clear();
    161     }
    162   }
    163   return 0;
    164 }
  • 相关阅读:
    WPS设置去广告
    Android,几款apk工具
    Eclipse 使用
    linux su和sudo命令的区别
    CentOS下安装SecureCRT的sz/rz工具包
    CentOS下安装SecureCRT的sz/rz工具包
    CentOS下安装SecureCRT的sz/rz工具包
    VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
    修改CentOS系统的默认启动级别
    修改CentOS系统的默认启动级别
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/5784865.html
Copyright © 2020-2023  润新知