计蒜客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\n",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\n",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\n",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\n",ans);
137         }
138         else 
139         {
140             update(1,1,n-1,k,s,t);
141         }
142     }   
143 }

 

posted @ 2017-09-16 21:43  Z-Y-Y-S  阅读(485)  评论(0编辑  收藏  举报