zoukankan      html  css  js  c++  java
  • 计蒜客NOIP模拟赛(3)D1T3 任性的国王

    X 国的地图可以被看作一个两行 nn 列的网格状图。现在 X 国需要修建铁路,然而该国的国王非常小气,他只想保证位于某两列之间的所有城市互相可以到达就行了,在此基础上,他希望所花费的代价最小。

    铁路可以建在任何两个相邻的点之间,使他们可以互相到达。可以作为工作人员,你已经整理出了为每一对相邻城市架设铁路所需要的花费。你需要准备好回答国王如下形式的问题。

    对于 (i,j)(i,j):当前情况下,使第 ii 列到第 jj 列之间的所有城市连通的最小代价是多少(列下标从 11 开始)?注意不能用其他列的城市。

    然而你还有更大的困难,随着时间变化,使用某些边作为铁路的代价会发生改变,你必须有效率地处理这些变化。

    输入格式

    第一行两个正整数 n,m,表示该国有 2 行 n 列以及 m个询问或者操作。

    第二行 3n-2个数,前 n-1个数依次表示在第一行的 n-1 条边上修建铁路的代价。

    接下来 n-1 个数,依次表示在第二行的 n-1 条边上修建铁路的代价。

    最后 n 个数,依次表示在第 1列到第 n列的边上修建铁路的代价。

    接下来 m 行的输入具有如下形式,K,S,T其中

    若 K=1,则表示询问当前状态下,使所有第 S 列到第 T 列之间的城市连通需要的最小代价。

    若 K=2,则表示位于第 1 行第 S 列的点到第 1 行第 S+1 列的点之间的边上修建铁路的代价变为 T。

    若 K=3,则表示位于第 2 行第 S 列的点和第 2 行第 S+1 列的点之间的边上修建铁路的代价变为 T。

    若 K=4,则表示第 S 列的边上修建铁路的代价变为 T。

    输出格式

    依次对每个询问,用一行输出相应的答案。

    数据范围与约定

    对于 30% 的数据:n,m≤2000。

    另有 30% 的数据:所有竖边的代价为 0 且永不改变。

    对于全部数据:n,m<10^5

    所有输入和输出数据保证合法,且不超过 2^{31}-1

    样例输入

    4 14
    2 3 4 3 1 1 1 5 4 7
    1 1 2
    1 2 3
    1 1 3
    1 2 4
    2 1 5
    1 1 4
    4 2 1
    1 1 3
    1 2 3
    1 2 4
    3 3 100
    1 3 4
    1 2 4
    1 1 4
    样例输出

    6
    8
    10
    13
    17
    9
    5
    10
    15
    16
    20

    暴力显然可以每一次查询做一次最小生成树

    一开始贪心,每一列选两个最小的边,用线段树维护,然后选一个最小的未选边

    但这样显然不能保证图连通和最优

    我们要想办法用数据结构来优化查询和修改,这里用线段树

    w[rt][0/1][0/1]表示rt区间左,右是否有竖边的最小值

    这样就可以通过左右区间合并来维护和查询

    注意当区间只有一个元素时

    w[rt][0][1]=a[l]+b[l]+c[l+1]

    每一个节点都要算上下一个点的竖边,合并时要减去重复的竖边

    详情见代码,这样是可以保证图连通的

    s=t时要特判

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 typedef long long lol;
      7 struct XXX
      8 {
      9  lol a[2][2]; 
     10 };
     11 lol w[800001][2][2],a[200001],b[200001],c[200001];
     12 int n,m;
     13 void pushup(int rt,int mid)
     14 {int i,j;
     15     for (i=0;i<=1;i++)
     16         for (j=0;j<=1;j++)
     17         {
     18             w[rt][i][j]=1e9;
     19           lol cost=w[rt*2][i][1]+w[rt*2+1][1][j]-c[mid+1];  
     20             w[rt][i][j]=min(w[rt][i][j],cost);
     21             cost=w[rt*2][i][0]+w[rt*2+1][1][j]-c[mid+1];  
     22             w[rt][i][j]=min(w[rt][i][j],cost);
     23             cost=w[rt*2][i][1]+w[rt*2+1][0][j]-c[mid+1];  
     24             w[rt][i][j]=min(w[rt][i][j],cost);
     25         }
     26 }
     27 void build(int rt,int l,int r)
     28 {
     29  if (l>r) return;
     30     if (l==r)
     31     {
     32         lol tot=a[l]+b[l]+c[l]+c[l+1];
     33         w[rt][1][0]=tot-c[l+1];
     34         w[rt][1][1]=tot-(a[l]+b[l]+abs(b[l]-a[l]))/2;
     35         w[rt][0][0]=1e9;
     36         w[rt][0][1]=tot-c[l];
     37         return;
     38     }
     39     int mid=(l+r)/2;
     40     build(rt*2,l,mid);
     41     build(rt*2+1,mid+1,r);
     42 pushup(rt,mid);
     43 }
     44 void ask(int rt,int l,int r,int L,int R,XXX &p)
     45 {int i,j;
     46  if (l>r) return;
     47     if (l>=L&&r<=R)
     48     {
     49         for (i=0;i<=1;i++)
     50             for (j=0;j<=1;j++)
     51             p.a[i][j]=w[rt][i][j];
     52         return;
     53     }
     54     XXX p1,p2;
     55     if (l==r) return;
     56  int mid=(l+r)/2;
     57  if (L>=mid+1)
     58  {
     59      ask(rt*2+1,mid+1,r,L,R,p2);
     60      for (i=0;i<=1;i++) 
     61          for (j=0;j<=1;j++)
     62              p.a[i][j]=p2.a[i][j];
     63      return;
     64  }
     65  if (R<=mid)
     66  {
     67      ask(rt*2,l,mid,L,R,p1);
     68      for (i=0;i<=1;i++) 
     69          for (j=0;j<=1;j++)
     70              p.a[i][j]=p1.a[i][j];
     71      return;
     72  }
     73     ask(rt*2,l,mid,L,R,p1);
     74     ask(rt*2+1,mid+1,r,L,R,p2);
     75   for (i=0;i<=1;i++)
     76       for (j=0;j<=1;j++)
     77       {
     78           p.a[i][j]=1e9;
     79            lol cost=p1.a[i][1]+p2.a[1][j]-c[mid+1];  
     80             p.a[i][j]=min(p.a[i][j],cost);
     81             cost=p1.a[i][0]+p2.a[1][j]-c[mid+1];  
     82             p.a[i][j]=min(p.a[i][j],cost);
     83             cost=p1.a[i][1]+p2.a[0][j]-c[mid+1];  
     84             p.a[i][j]=min(p.a[i][j],cost);
     85       }     
     86 }
     87 void update(int rt,int l,int r,lol k,lol x,lol d)
     88 {
     89  if (l>r) return;
     90     if (l==r)
     91     {
     92         if (k==2) a[x]=d;
     93         if (k==3) b[x]=d;
     94         if (k==4) c[x]=d;
     95          lol tot=a[l]+b[l]+c[l]+c[l+1];
     96         w[rt][1][0]=tot-c[l+1];
     97         w[rt][1][1]=tot-(a[l]+b[l]+abs(b[l]-a[l]))/2;
     98         w[rt][0][0]=1e9;
     99         w[rt][0][1]=tot-c[l];
    100         return;
    101     }
    102     int mid=(l+r)/2;
    103     if (k==4)
    104     {
    105          if (x<=mid+1) update(rt*2,l,mid,k,x,d);
    106          if (x>=mid+1) update(rt*2+1,mid+1,r,k,x,d); 
    107     }
    108     else 
    109     {
    110     if (x<=mid) update(rt*2,l,mid,k,x,d);
    111     else update(rt*2+1,mid+1,r,k,x,d);
    112     }
    113 pushup(rt,mid);
    114 }
    115 int main()
    116 {int i;
    117 lol k,s,t;
    118  XXX p;
    119     cin>>n>>m;
    120     for (i=1;i<=n-1;i++)
    121         scanf("%lld",&a[i]);
    122     for (i=1;i<=n-1;i++)
    123         scanf("%lld",&b[i]);
    124     for (i=1;i<=n;i++)
    125         scanf("%lld",&c[i]);
    126     build(1,1,n-1);
    127     while (m--)
    128     {lol ans=2e9;
    129         scanf("%lld%lld%lld",&k,&s,&t);
    130         if (k==1)
    131         {
    132             if (s==t)
    133             {printf("%lld
    ",c[s]);continue;}
    134             ask(1,1,n-1,s,t-1,p);
    135             ans=min(min(p.a[0][0],p.a[0][1]),min(p.a[1][0],p.a[1][1]));
    136             printf("%lld
    ",ans);
    137         }
    138         else 
    139         {
    140             update(1,1,n-1,k,s,t);
    141         }
    142     }   
    143 }
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 typedef long long lol;
      7 struct XXX
      8 {
      9  lol a[2][2]; 
     10 };
     11 lol w[800001][2][2],a[200001],b[200001],c[200001];
     12 int n,m;
     13 void pushup(int rt,int mid)
     14 {int i,j;
     15     for (i=0;i<=1;i++)
     16         for (j=0;j<=1;j++)
     17         {
     18             w[rt][i][j]=1e9;
     19           lol cost=w[rt*2][i][1]+w[rt*2+1][1][j]-c[mid+1];  
     20             w[rt][i][j]=min(w[rt][i][j],cost);
     21             cost=w[rt*2][i][0]+w[rt*2+1][1][j]-c[mid+1];  
     22             w[rt][i][j]=min(w[rt][i][j],cost);
     23             cost=w[rt*2][i][1]+w[rt*2+1][0][j]-c[mid+1];  
     24             w[rt][i][j]=min(w[rt][i][j],cost);
     25         }
     26 }
     27 void build(int rt,int l,int r)
     28 {
     29  if (l>r) return;
     30     if (l==r)
     31     {
     32         lol tot=a[l]+b[l]+c[l]+c[l+1];
     33         w[rt][1][0]=tot-c[l+1];
     34         w[rt][1][1]=tot-(a[l]+b[l]+abs(b[l]-a[l]))/2;
     35         w[rt][0][0]=1e9;
     36         w[rt][0][1]=tot-c[l];
     37         return;
     38     }
     39     int mid=(l+r)/2;
     40     build(rt*2,l,mid);
     41     build(rt*2+1,mid+1,r);
     42 pushup(rt,mid);
     43 }
     44 void ask(int rt,int l,int r,int L,int R,XXX &p)
     45 {int i,j;
     46  if (l>r) return;
     47     if (l>=L&&r<=R)
     48     {
     49         for (i=0;i<=1;i++)
     50             for (j=0;j<=1;j++)
     51             p.a[i][j]=w[rt][i][j];
     52         return;
     53     }
     54     XXX p1,p2;
     55     if (l==r) return;
     56  int mid=(l+r)/2;
     57  if (L>=mid+1)
     58  {
     59      ask(rt*2+1,mid+1,r,L,R,p2);
     60      for (i=0;i<=1;i++) 
     61          for (j=0;j<=1;j++)
     62              p.a[i][j]=p2.a[i][j];
     63      return;
     64  }
     65  if (R<=mid)
     66  {
     67      ask(rt*2,l,mid,L,R,p1);
     68      for (i=0;i<=1;i++) 
     69          for (j=0;j<=1;j++)
     70              p.a[i][j]=p1.a[i][j];
     71      return;
     72  }
     73     ask(rt*2,l,mid,L,R,p1);
     74     ask(rt*2+1,mid+1,r,L,R,p2);
     75   for (i=0;i<=1;i++)
     76       for (j=0;j<=1;j++)
     77       {
     78           p.a[i][j]=1e9;
     79            lol cost=p1.a[i][1]+p2.a[1][j]-c[mid+1];  
     80             p.a[i][j]=min(p.a[i][j],cost);
     81             cost=p1.a[i][0]+p2.a[1][j]-c[mid+1];  
     82             p.a[i][j]=min(p.a[i][j],cost);
     83             cost=p1.a[i][1]+p2.a[0][j]-c[mid+1];  
     84             p.a[i][j]=min(p.a[i][j],cost);
     85       }     
     86 }
     87 void update(int rt,int l,int r,lol k,lol x,lol d)
     88 {
     89  if (l>r) return;
     90     if (l==r)
     91     {
     92         if (k==2) a[x]=d;
     93         if (k==3) b[x]=d;
     94         if (k==4) c[x]=d;
     95          lol tot=a[l]+b[l]+c[l]+c[l+1];
     96         w[rt][1][0]=tot-c[l+1];
     97         w[rt][1][1]=tot-(a[l]+b[l]+abs(b[l]-a[l]))/2;
     98         w[rt][0][0]=1e9;
     99         w[rt][0][1]=tot-c[l];
    100         return;
    101     }
    102     int mid=(l+r)/2;
    103     if (k==4)
    104     {
    105          if (x<=mid+1) update(rt*2,l,mid,k,x,d);
    106          if (x>=mid+1) update(rt*2+1,mid+1,r,k,x,d); 
    107     }
    108     else 
    109     {
    110     if (x<=mid) update(rt*2,l,mid,k,x,d);
    111     else update(rt*2+1,mid+1,r,k,x,d);
    112     }
    113 pushup(rt,mid);
    114 }
    115 int main()
    116 {int i;
    117 lol k,s,t;
    118  XXX p;
    119     cin>>n>>m;
    120     for (i=1;i<=n-1;i++)
    121         scanf("%lld",&a[i]);
    122     for (i=1;i<=n-1;i++)
    123         scanf("%lld",&b[i]);
    124     for (i=1;i<=n;i++)
    125         scanf("%lld",&c[i]);
    126     build(1,1,n-1);
    127     while (m--)
    128     {lol ans=2e9;
    129         scanf("%lld%lld%lld",&k,&s,&t);
    130         if (k==1)
    131         {
    132             if (s==t)
    133             {printf("%lld
    ",c[s]);continue;}
    134             ask(1,1,n-1,s,t-1,p);
    135             ans=min(min(p.a[0][0],p.a[0][1]),min(p.a[1][0],p.a[1][1]));
    136             printf("%lld
    ",ans);
    137         }
    138         else 
    139         {
    140             update(1,1,n-1,k,s,t);
    141         }
    142     }   
    143 }
  • 相关阅读:
    一次性能测试的面试问题
    一次APP测试的感悟
    《程序员跳槽全攻略》读书笔记
    如果有人让你推荐编程技术书,请叫他看这个列表
    上班的一天
    马士兵Java视频教程 —— 学习顺序
    月薪3万的技术网站资源收集
    给32岁的自己一些答案
    《Vuser虚拟用户开发》读书笔记
    shell脚本异常:/bin/sh^M:bad interpreter: No such file or directory
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7533080.html
Copyright © 2011-2022 走看看