【BZOJ2459】 [BeiJing2011]神秘好人
阿新 • • 發佈:2017-06-25
上層 src fin 之間 class 。。 void 若是 can ,3,……,2N-1,第二行從左至右分別標號為2,4,……,2N。
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
8
13
10
Description
有一個神秘好人跟Bdcxq玩一個遊戲,如果Bdcxq成功完成了這個遊戲,那麽他將會得到一件禮物。 這個遊戲是這樣的: 有一個梯子形的圖如下,每條邊都有一個權值。神秘好人一開始會告訴Bdcxq每條邊的權值。
然後神秘好人會做這樣的事情:
1.神秘好人會修改某條邊的權值;
2.神秘老人會問你從一個點走到另一個點所需經過邊權和最小的權值和。
如果Bdcxq一直能答對問題,那麽他就完成了遊戲,也能得到禮物。
現在他請你編一個程序來幫他完成遊戲。
Input
輸入文件的第一行包含一個整數N,表示梯子總共含有2N個點,第一行從左至右分別標號為1
接下來有三行。
第一行有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
41 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
18
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]神秘好人