反正没时间写,先把简要题解(嘴巴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 }
View Code

相关文章: