瞭解超五類雙絞線原理與實際操作
阿新 • • 發佈:2020-10-13
線段樹
動態最大連續和(Ray, Pass me the dished, LA 3938)
1 #include <iostream> 2 #include <regex> 3 #include <limits.h> 4 #include <random> 5 6 #define debug 7 typedef long long ll; 8 using namespace std; 9 10 const int maxn = 500000; 11 12 int n, m; 13 void test();14 15 struct node { 16 // a, b sub 17 // c prefix index 18 // d suffix index 19 int a, b, c, d; 20 ll max_sub, max_prefix, max_suffix; 21 node(): a(-1), b(-1), c(-1), d(-1), max_sub(INT_MIN), max_prefix(INT_MIN), max_suffix(INT_MIN){} 22 node(int idx, int val) { 23 a = b = c = d = idx;24 max_sub = max_prefix = max_suffix = val; 25 } 26 }; 27 node arr[4 * maxn + 10]; 28 ll sum[maxn + 10]; 29 ll vals[maxn + 10]; 30 31 int ql, qr; 32 node query(int o, int L, int R) { 33 int M = (L + R) / 2; 34 if (ql <= L && R <= qr) return arr[o]; 35 if(ql <= M && !(M < qr)) { 36 return query(o * 2, L, M); 37 } else if (!(ql <= M) && M < qr) { 38 return query(o * 2 + 1, M + 1, R); 39 } else { 40 node ans; 41 node left = query(o * 2, L, M); 42 node right = query(o * 2 + 1, M + 1, R); 43 // 最大子陣列 44 if (right.max_sub > left.max_suffix + right.max_prefix) { 45 ans.max_sub = right.max_sub; 46 ans.a = right.a; 47 ans.b = right.b; 48 } else { 49 ans.max_sub = left.max_suffix + right.max_prefix; 50 ans.a = left.d; 51 ans.b = right.c; 52 } 53 if (left.max_sub > ans.max_sub || ((left.max_sub == ans.max_sub) && (left.a < ans.a || left.a == ans.a && left.b < ans.b))) { 54 ans.max_sub = left.max_sub; 55 ans.a = left.a; 56 ans.b = left.b; 57 } 58 59 // 最大字首 60 if (left.max_prefix >= right.max_prefix + sum[M] - sum[max(L, ql) - 1]) { 61 ans.max_prefix = left.max_prefix; 62 ans.c = left.c; 63 } else { 64 ans.max_prefix = right.max_prefix + sum[M] - sum[max(L, ql) - 1]; 65 ans.c = right.c; 66 } 67 68 // 最大字尾 69 if (left.max_suffix + sum[min(R, qr)] - sum[M] >= right.max_suffix) { 70 ans.max_suffix = left.max_suffix + sum[min(R, qr)] - sum[M]; 71 ans.d = left.d; 72 } else { 73 ans.max_suffix = right.max_suffix; 74 ans.d = right.d; 75 } 76 return ans; 77 } 78 } 79 80 ll p, v; 81 void update(int o, int L, int R) { 82 int l = o << 1; 83 int r = l + 1; 84 int M = (L + R) / 2; 85 if (L == R) { 86 arr[o] = node(L, v); 87 } else { 88 if (p <= M) update(o * 2, L, M); else update(o * 2 + 1, M + 1, R); 89 // max_sub 90 if (arr[r].max_sub > arr[l].max_suffix + arr[r].max_prefix) { 91 arr[o].max_sub = arr[r].max_sub; 92 arr[o].a = arr[r].a; 93 arr[o].b = arr[r].b; 94 } else { 95 arr[o].max_sub = arr[l].max_suffix + arr[r].max_prefix; 96 arr[o].a = arr[l].d; 97 arr[o].b = arr[r].c; 98 } 99 if (arr[l].max_sub > arr[o].max_sub || (arr[l].max_sub == arr[o].max_sub && (arr[l].a < arr[o].a || ((arr[l].a == arr[o].a) && arr[l].b < arr[o].b)))) { 100 arr[o].max_sub = arr[l].max_sub; 101 arr[o].a = arr[l].a; 102 arr[o].b = arr[l].b; 103 } 104 // max_prefix 105 if (arr[l].max_prefix >= arr[r].max_prefix + sum[M] - sum[L - 1]) { 106 arr[o].max_prefix = arr[l].max_prefix; 107 arr[o].c = arr[l].c; 108 } else { 109 arr[o].max_prefix = arr[r].max_prefix + sum[M] - sum[L - 1]; 110 arr[o].c = arr[r].c; 111 } 112 // max_suffix 113 if (arr[l].max_suffix + sum[R] - sum[M] >= arr[r].max_suffix) { 114 arr[o].max_suffix = arr[l].max_suffix + sum[R] - sum[M]; 115 arr[o].d = arr[l].d; 116 } else { 117 arr[o].max_suffix = arr[r].max_suffix; 118 arr[o].d = arr[r].d; 119 } 120 } 121 } 122 int main() { 123 #ifdef debug 124 if (freopen("data.in", "rb", stdin) == NULL){ 125 printf("Open data.in failed\n"); 126 return 1; 127 } 128 if (freopen("data.out", "wb", stdout) == NULL) { 129 printf("Open data.out failed!\n"); 130 return 1; 131 } 132 #endif 133 int Case = 1; 134 while (cin >> n >> m) { 135 for (int i = 1; i <= n; i++) { 136 cin >> vals[i]; 137 sum[i] = sum[i - 1] + vals[i]; 138 } 139 140 for (int i = 1; i <= n; i++) { 141 p = i; 142 v = vals[i]; 143 update(1, 1, n); 144 145 } 146 printf("Case %d:\n", Case++); 147 for (int i = 0; i < m; i++) { 148 cin >> ql >> qr; 149 node ret = query(1, 1, n); 150 cout << ret.a << " " << ret.b << endl; 151 } 152 } 153 // test(); 154 return 0; 155 } 156 157 pair<int, int> solve(int a, int b) { 158 ll ret = INT_MIN; 159 int x, y; 160 for (int i = a; i <= b; i++) { 161 ll sum = 0; 162 for (int j = i; j <= b; j++) { 163 sum = ::sum[j] - ::sum[i - 1]; 164 if (sum > ret || sum == ret && (i < x || i == x && j < y)) { 165 ret = sum; 166 x = i; 167 y = j; 168 } 169 } 170 } 171 return make_pair(x, y); 172 } 173 void test() { 174 n = 1600; 175 m = 10000; 176 uniform_int_distribution<> u(-10, 30); 177 default_random_engine e; 178 e.seed(3); 179 for (int i = 1; i <= n; i++) { 180 vals[i] = u(e); 181 182 cout << vals[i] << " "; 183 sum[i] = sum[i - 1] + vals[i]; 184 } 185 cout << endl; 186 for (int i = 1; i <= n; i++) { 187 p = i; 188 v = vals[i]; 189 update(1, 1, n); 190 int xxx; 191 xxx++; 192 } 193 int Case = 1; 194 uniform_int_distribution<> u2(1, n); 195 for (int i = 1; i <= 2000; i++) { 196 int a = u2(e); 197 int b = u2(e); 198 if (a <= b){ 199 ql = a; 200 qr = b; 201 node ret = query(1, 1, n); 202 pair<int, int> ret2 = solve(a, b); 203 if (ret.a != ret2.first || ret.b != ret2.second) { 204 printf("[%d, %d] [%d, %d] [%d %d] [%d %d]\n", a, b, ret.a, ret.b, ret2.first, ret2.second, ret.max_sub, sum[ret2.second] - sum[ret2.first - 1]); 205 } 206 207 } 208 209 } 210 cout << vals[1546] << endl; 211 cout << vals[1282] << endl; 212 cout << vals[1218] << endl; 213 }