1. 程式人生 > >【BZOJ2459】 [BeiJing2011]神秘好人

【BZOJ2459】 [BeiJing2011]神秘好人

上層 src fin 之間 class 。。 void 若是 can

Description

有一個神秘好人跟Bdcxq玩一個遊戲,如果Bdcxq成功完成了這個遊戲,那麽他將會得到一件禮物。 這個遊戲是這樣的: 有一個梯子形的圖如下,每條邊都有一個權值。 技術分享

神秘好人一開始會告訴Bdcxq每條邊的權值。

然後神秘好人會做這樣的事情:

1.神秘好人會修改某條邊的權值;

2.神秘老人會問你從一個點走到另一個點所需經過邊權和最小的權值和。

如果Bdcxq一直能答對問題,那麽他就完成了遊戲,也能得到禮物。

現在他請你編一個程序來幫他完成遊戲。

Input

輸入文件的第一行包含一個整數N,表示梯子總共含有2N個點,第一行從左至右分別標號為1

3,……,2N-1第二行從左至右分別標號為24,……,2N

接下來有三行。

第一行有N-1個整數,依次表示上層相鄰兩點間的初始權值。

第二行有N個整數,依次表示兩層之間的邊的初始權值。

第三行有N-1個整數,依次表示下層相鄰兩點間的初始權值。

接下來一行包含一個整數M,表示神秘好人在遊戲開始後的操作。

接下來M行:

每行第一個整數若是0,表示這是一個修改操作,接下來會有3個整數Ai,Bi,Ci,Ai為0,1,2分別代表這條邊屬於上層邊,中間邊和下層邊,Bi表示這條邊是這一層從左向右數的第Bi條邊,Ci表示要修改成的邊權。

每行第一個整數若是1,表示這是一個詢問操作,接下來會有2個整數Ai,Bi,詢問Ai到Bi的經過邊的最小權值和。

Output

對於每次詢問操作你需要輸出一行包含一個整數,為最小的邊權值和。

Sample Input

4
1 2 7
1 3 4 8
4 5 6
5
1 1 2
1 2 6
1 1 8
0 1 3 1
1 1 8

Sample Output

1
8
13
10

HINT

100%的數據滿足N,M≤ 100000。

Solution

用線段樹維護僅在這個區間內走時四個角的最短路的鄰接矩陣,然後修改詢問就強行維護一波就好啦。這題細節比較多,要註意一下。。。

Code

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 #define R register
  6 #define maxn 100010
  7 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
  8 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
  9 typedef long long ll;
 10 struct Data {
 11     ll d[4][4];
 12     inline void init()
 13     {
 14         memset(d, 63, sizeof (d));
 15         for (R int i = 0; i < 4; ++i) d[i][i] = 0;
 16     }
 17     inline void floyd()
 18     {
 19         for (R int k = 0; k < 4; ++k)
 20             for (R int i = 0; i < 4; ++i)
 21                 for (R int j = 0; j < 4; ++j)
 22                     cmin(d[i][j], d[i][k] + d[k][j]);
 23     }
 24     inline Data operator + (const Data &that) const
 25     {
 26         R Data ret; ret.init();
 27         ret.d[0][1] = ret.d[1][0] = dmin(d[0][1], d[0][2] + that.d[0][1] + d[3][1]);
 28         ret.d[2][3] = ret.d[3][2] = dmin(that.d[2][3], that.d[2][0] + d[2][3] + that.d[1][3]);
 29 
 30         ret.d[0][2] = ret.d[2][0] = dmin(d[0][2] + that.d[0][2], d[0][3] + that.d[1][2]);
 31         ret.d[0][3] = ret.d[3][0] = dmin(d[0][2] + that.d[0][3], d[0][3] + that.d[1][3]);
 32         ret.d[1][2] = ret.d[2][1] = dmin(d[1][2] + that.d[0][2], d[1][3] + that.d[1][2]);
 33         ret.d[1][3] = ret.d[3][1] = dmin(d[1][2] + that.d[0][3], d[1][3] + that.d[1][3]);
 34 //        ret.floyd();
 35         return ret;
 36     }
 37 } ;
 38 int u[maxn], m[maxn], d[maxn];
 39 Data tr[maxn << 2];
 40 void update(R int o)
 41 {
 42     tr[o] = tr[o << 1] + tr[o << 1 | 1];
 43 }
 44 void build(R int o, R int l, R int r)
 45 {
 46     if (l == r)
 47     {
 48         tr[o].init();
 49         tr[o].d[0][1] = tr[o].d[1][0] = m[l];
 50         tr[o].d[0][2] = tr[o].d[2][0] = u[l];
 51         tr[o].d[1][3] = tr[o].d[3][1] = d[l];
 52         tr[o].d[2][3] = tr[o].d[3][2] = m[l + 1];
 53         tr[o].floyd();
 54         return ;
 55     }
 56     R int mid = l + r >> 1;
 57     build(o << 1, l, mid);
 58     build(o << 1 | 1, mid + 1, r);
 59     update(o);
 60 }
 61 int ql, qr;
 62 void modify(R int o, R int l, R int r)
 63 {
 64     if (l == r)
 65     {
 66         tr[o].init();
 67         tr[o].d[0][1] = tr[o].d[1][0] = m[l];
 68         tr[o].d[0][2] = tr[o].d[2][0] = u[l];
 69         tr[o].d[1][3] = tr[o].d[3][1] = d[l];
 70         tr[o].d[2][3] = tr[o].d[3][2] = m[l + 1];
 71         tr[o].floyd();
 72         return ;
 73     }
 74     R int mid = l + r >> 1;
 75     if (ql <= mid) modify(o << 1, l, mid);
 76     else modify(o << 1 | 1, mid + 1, r);
 77     update(o);
 78 }
 79 Data query(R int o, R int l, R int r)
 80 {
 81     if (ql <= l && r <= qr) return tr[o];
 82     R Data ret;
 83     R int mid = l + r >> 1;
 84     if (ql <= mid && qr <= mid) return query(o << 1, l, mid);
 85     if (mid < ql && mid < qr) return query(o << 1 | 1, mid + 1, r);
 86     return query(o << 1, l, mid) + query(o << 1 | 1, mid + 1, r);
 87 }
 88 int main()
 89 {
 90     R int n; scanf("%d", &n);
 91     for (R int i = 1; i < n; ++i) scanf("%d", u + i);
 92     for (R int i = 1; i <= n; ++i) scanf("%d", m + i);
 93     for (R int i = 1; i < n; ++i) scanf("%d", d + i);
 94     build(1, 1, n - 1);
 95     R int q; scanf("%d", &q);
 96     for (; q; --q)
 97     {
 98         R int opt, a, b, c; scanf("%d%d%d", &opt, &a, &b);
 99         if (!opt)
100         {
101             scanf("%d", &c);
102             if (a == 0) u[b] = c;
103             else if (a == 1) m[b] = c;
104             else d[b] = c;
105             
106             if (a != 1 || b != n) ql = b, modify(1, 1, n - 1);
107             if (a == 1 && b != 1) ql = b - 1, modify(1, 1, n - 1);
108         }
109         else
110         {
111             R int l = (a + 1) >> 1, lt = (a + 1) & 1, r = (b + 1) >> 1, rt = (b + 1) & 1;
112             l > r ? std::swap(l, r), std::swap(lt, rt), 1 : 0;
113             
114             R Data v1, v2, v3; v1.init(); v2.init(); v3.init();
115             ql = 1, qr = l - 1;
116             if (ql <= qr) v1 = query(1, 1, n - 1);
117             ql = l; qr = r - 1;
118             if (ql <= qr) v2 = query(1, 1, n - 1);
119             ql = r; qr = n - 1;
120             if (ql <= qr) v3 = query(1, 1, n - 1);
121             
122             R ll ans = 0;
123             if (l == r)
124             {
125                 ans = dmin(v1.d[2 + lt][2 + rt], v3.d[lt][rt]);
126             }
127             else
128             {
129 //                for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v1.d[i][j]);
130 //                for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v2.d[i][j]);
131 //                for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v3.d[i][j]);
132                 ans = v2.d[lt][2 + rt];
133                 cmin(ans, v1.d[2][3] + v2.d[lt ^ 1][2 + rt]);
134                 cmin(ans, v2.d[lt][2 + (rt ^ 1)] + v3.d[0][1]);
135                 cmin(ans, v1.d[2][3] + v2.d[lt ^ 1][2 + (rt ^ 1)] + v3.d[0][1]);
136 /*                cmin(v2.d[0][1], v1.d[2][3]);
137                 cmin(v2.d[2][3], v3.d[0][1]);
138                 v2.floyd();
139                 ans = v2.d[lt][2 + rt];*/
140             }
141             printf("%lld\n", ans);
142         }
143     }
144     return 0;
145 }
146 /*
147 4
148 1 2 7
149 1 3 4 8
150 4 5 6
151 5
152 1 1 2
153 1 2 6
154 1 1 8
155 0 1 3 1
156 1 1 8
157 */

【BZOJ2459】 [BeiJing2011]神秘好人