#pragma GCC optimize(3) #include <stdio.h> #include <memory.h> #define BUFSIZ 1048576 #define MOD 10000000 #define MUTMOD(x) ((x<<24)-(x<<22)-(x<<21)-(x<<19)+(x<<16)-(x<<14)-(x<<13)-(x<<11)-(x<<8)-(x<<7))
typedef struct BigNum { unsigned long long Num[72000]; int Last; }BigNum;
BigNum list[3], * n = &list[0], * ans = &list[1], * tmp = &list[2]; char output[500050];
inline char readChar() { static char buffer[BUFSIZ], * now = buffer + BUFSIZ, * end = buffer + BUFSIZ; if (now == end) { if (end < buffer + BUFSIZ) return EOF; end = (buffer + fread(buffer, 1, BUFSIZ, stdin)); now = buffer; } return *now++; }
inline char readUInt(unsigned int* dst) { register char ch; while ((ch = readChar()) < '0') if (ch == EOF) return 0; *dst = ch ^ '0'; while ((ch = readChar()) >= '0') * dst = (*dst << 3) + (*dst << 1) + (ch ^ '0'); return 1; }
inline BigNum* BigMult(BigNum* dst, BigNum* times) { memset(tmp, 0, sizeof(BigNum)); tmp->Last = dst->Last + times->Last; register unsigned long long div; for (int i = 0; i <= dst->Last; i++) { if (dst->Num[i]) { for (int j = 0; j <= times->Last; j++) { if (times->Num[j]) tmp->Num[i + j] += dst->Num[i] * times->Num[j]; } } } for (int i = 0; i <= tmp->Last; i++) { if (tmp->Num[i] >= MOD) { div = tmp->Num[i] / MOD; tmp->Num[i] = tmp->Num[i] - MUTMOD(div); tmp->Num[i + 1] += div; if (tmp->Last < i + 1) tmp->Last = i + 1; } } BigNum* res = tmp; tmp = dst; return res; }
void pow(BigNum* dst, BigNum* src, int m) { dst->Num[0] = 1, dst->Last = 0; for (;; m >>= 1) { if (m & 1) { dst = BigMult(dst, src); if (m == 1) break; } src = BigMult(src, src); } ans = dst; n = src; }
void putUBigNum(char buffer[], BigNum* src) { register char* st = buffer; register unsigned long long div1, div2; for (int i = src->Last; ~i; i--, st += 7) { st[6] = (src->Num[i] - ((div1 = src->Num[i] / 10) << 3) - (div1 << 1)) | '0'; st[5] = (div1 - ((div2 = div1 / 10) << 3) - (div2 << 1)) | '0'; st[4] = (div2 - ((div1 = div2 / 10) << 3) - (div1 << 1)) | '0'; st[3] = (div1 - ((div2 = div1 / 10) << 3) - (div2 << 1)) | '0'; st[2] = (div2 - ((div1 = div2 / 10) << 3) - (div1 << 1)) | '0'; st[1] = (div1 - ((div2 = div1 / 10) << 3) - (div2 << 1)) | '0'; st[0] = (div2 - ((div1 = div2 / 10) << 3) - (div1 << 1)) | '0'; } *st = '\0', st = buffer; while (*st == '0') st++; puts(st); }
int main() { int m; while ((readUInt(&n->Num[0]), readUInt(&m)) && n->Num[0] + m) { n->Last = 0; pow(ans, n, m); putUBigNum(output, ans); } return 0; }
|