反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下。
upd:任务倒是完成了,我也自闭了。
CST2018 2-1 Meteorites:
乘法版的石子合并,堆 + 高精度。
写起来有点烦貌似。
upd:由于内存问题我高精度是动态开点,同时用的是可并堆(比较简单)。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 5 using namespace std; 6 typedef double lf; 7 typedef long long ll; 8 const lf pi = acos(-1.0); 9 const int N = 200005; 10 const int MaxLen = 2000005; 11 const int MOD = 10000; 12 13 struct BigNumber; 14 inline int getint(); 15 inline void getInt(BigNumber &res); // get Big number 16 inline void print(ll *num, int Len); 17 18 template<class T> inline void swap(T &x, T &y) { 19 register T tmp; 20 tmp = x, x = y, y = tmp; 21 } 22 23 int n; 24 25 struct Complex { 26 lf x, y; 27 28 Complex(lf _x = 0, lf _y = 0) : x(_x), y(_y) { 29 } 30 ~Complex() { 31 } 32 33 Complex operator +(const Complex &_c) { 34 return Complex(x + _c.x, y + _c.y); 35 } 36 Complex operator -(const Complex &_c) { 37 return Complex(x - _c.x, y - _c.y); 38 } 39 Complex operator *(const Complex &_c) { 40 return Complex(x * _c.x - y * _c.y, x * _c.y + y * _c.x); 41 } 42 Complex operator *(const lf &_x) { 43 return Complex(_x * x, _x * y); 44 } 45 Complex operator !() { 46 return Complex(x, -y); 47 } 48 } w[MaxLen], A[MaxLen], B[MaxLen], C[MaxLen]; 49 50 struct BigNumber { 51 ll *x; 52 int len; 53 54 BigNumber() { 55 x = new ll[1]; 56 x[0] = 0; 57 len = 0; 58 } 59 60 void destroy() { 61 if (x) delete[] x; 62 } 63 64 ~BigNumber() { 65 destroy(); 66 } 67 68 void ChangeSize(int length) { 69 if (x) delete[] x; 70 x = new ll[length + 1]; 71 memset(x, 0, (length + 1) * sizeof(x)); 72 len = 0; 73 } 74 75 void zero() { 76 ChangeSize(0); 77 x[0] = 0; 78 len = 0; 79 } 80 void one() { 81 ChangeSize(0); 82 x[0] = 1; 83 len = 0; 84 } 85 86 void copy(const BigNumber &_num) { 87 ChangeSize(_num.len); 88 len = _num.len; 89 for (int i = len; i >= 0; --i) 90 x[i] = _num.x[i]; 91 } 92 93 inline bool operator > (const BigNumber &_num) const { 94 if (len > _num.len) return 1; 95 if (len < _num.len) return 0; 96 for (int i = len; i >= 0; --i) { 97 if (x[i] > _num.x[i]) return 1; 98 if (x[i] < _num.x[i]) return 0; 99 } 100 return 1; 101 } 102 103 void print() { 104 for (int i = len; i >= 0; --i) 105 printf(i == len ? "%lld" : "%04lld", x[i]); 106 puts(""); 107 } 108 }; 109 110 struct heap { 111 heap *ls, *rs; 112 BigNumber num; 113 int dep; 114 115 void *operator new(size_t) { 116 static heap mempool[N << 2], *c = mempool; 117 c -> ls = c -> rs = NULL; 118 c -> dep = 1; 119 c -> num.zero(); 120 return c++; 121 } 122 123 inline void get_value(const BigNumber &_num) { 124 num.copy(_num); 125 } 126 127 #define Dep(p) (p ? p -> dep : 0) 128 inline void update() { 129 dep = Dep(rs) + 1; 130 } 131 132 friend heap* merge(heap *x, heap *y) { 133 if (!x) return y; 134 if (!y) return x; 135 if (x -> num > y -> num) swap(x, y); 136 x -> rs = merge(x -> rs, y); 137 if (Dep(x -> rs) > Dep(x -> ls)) 138 swap(x -> ls, x -> rs); 139 x -> update(); 140 return x; 141 } 142 #undef Dep 143 144 inline heap* pop() { 145 this -> num.ChangeSize(0); 146 return merge(ls, rs); 147 } 148 } *Root; 149 150 151 void work(const BigNumber &a, const BigNumber &b, BigNumber &c) { 152 int n = a.len, m = b.len, l = a.len + b.len + 4; 153 c.ChangeSize(l); 154 155 for (int k = 0; k <= l; ++k) c.x[k] = 0; 156 157 for (int i = 0; i <= n; ++i) 158 for (int j = 0; j <= m; ++j) 159 c.x[i + j] += a.x[i] * b.x[j]; 160 for (int k = 0; k < l; ++k) { 161 c.x[k + 1] += c.x[k] / MOD; 162 c.x[k] %= MOD; 163 } 164 165 while (c.x[l] == 0) --l; 166 c.len = l; 167 } 168 169 int main() { 170 BigNumber ans, tmp, a, b, c; 171 heap *tmp_node; 172 173 n = getint(); 174 tmp.one(); 175 176 Root = new()heap; 177 Root -> get_value(tmp); 178 179 for (int i = 1; i <= n; ++i) { 180 getInt(tmp); 181 tmp_node = new()heap; 182 tmp_node -> get_value(tmp); 183 184 Root = merge(Root, tmp_node); 185 } 186 187 188 ans.one(); 189 for (int i = 1; i <= n; ++i) { 190 a.copy(Root -> num); 191 Root = Root -> pop(); 192 b.copy(Root -> num); 193 Root = Root -> pop(); 194 /* 195 puts("a and b:"); 196 a.print(); 197 b.print(); 198 puts("---------"); 199 */ 200 work(a, b, c); 201 /* 202 puts("c:"); 203 c.print(); 204 */ 205 tmp.copy(ans); 206 if (i != 1) { 207 /* 208 puts("----"); 209 tmp.print(); 210 c.print(); 211 */ 212 work(tmp, c, ans); 213 } 214 /* 215 puts("ans:"); 216 ans.print(); 217 */ 218 tmp_node = new()heap; 219 tmp_node -> get_value(c); 220 221 Root = merge(Root, tmp_node); 222 } 223 ans.print(); 224 225 return 0; 226 } 227 228 const int BUF_SIZE = 30; 229 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1; 230 #define isdigit(x) ('0' <= x && x <= '9') 231 #define PTR_NEXT() { \ 232 if (++buf_s == buf_t) \ 233 buf_s = buf, buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); \ 234 } 235 236 int getint() { 237 register int x = 0; 238 while (!isdigit(*buf_s)) PTR_NEXT(); 239 while (isdigit(*buf_s)) { 240 x = x * 10 + *buf_s - '0'; 241 PTR_NEXT(); 242 } 243 return x; 244 } 245 246 void getInt(BigNumber &res) { 247 static ll num[50]; 248 static int len, Len, cnt, base; 249 memset(num, 0, sizeof(num)), len = 0; 250 for (int i = 0; i < 50; ++i) num[i] = 0; 251 252 while (!isdigit(*buf_s)) PTR_NEXT(); 253 while (isdigit(*buf_s) && buf_s != buf_t) { 254 num[len++] = *buf_s - '0'; 255 PTR_NEXT(); 256 } 257 len -= 1; 258 259 res.ChangeSize((len + 4) / 4 - 1); 260 Len = -1, cnt = 0; 261 for (int i = len; i >= 0; --i) { 262 cnt++; 263 if (cnt % 4 == 1) Len += 1, base = 1; 264 res.x[Len] += base * num[i]; 265 base *= 10; 266 } 267 res.len = Len; 268 269 /* 270 for (int i = 0; i <= len; ++i) 271 printf("%lld ", num[i]); 272 puts(""); 273 274 res.print(); 275 */ 276 }