#pragma GCC optimize("Ofast,unroll-loops") #include #include #include #define IN_CAP (1u << 26) // 64 MiB #define OUT_CAP (1u << 24) // 16 MiB static unsigned char inbuf[IN_CAP]; static char outbuf[OUT_CAP]; static uint32_t sums[1000000]; /* 0000 ~ 9999 を4文字にしたもの */ static uint32_t dig4[10000]; /* 先頭から何文字捨てればよいか */ static unsigned char lead4[10000]; static inline uint32_t read_u32(unsigned char **pp) { unsigned char *p = *pp; uint32_t x = 0; unsigned c; /* 呼び出し開始時点では必ず数字。 数字の直後の空白/改行を1文字消費して終了する。 */ while ((c = (unsigned)(*p++ - (unsigned char)'0')) <= 9u) { x = x * 10u + c; } *pp = p; return x; } int main(void) { /* 入力全体を最初に読む。 最大でもだいたい 40MB 程度なので 64MiB に収まる。 */ size_t nread = 0; while (nread + 1 < IN_CAP) { ssize_t z = read( STDIN_FILENO, inbuf + nread, IN_CAP - 1 - nread ); if (z <= 0) break; nread += (size_t)z; } inbuf[nread] = '\n'; unsigned char *p = inbuf; uint32_t H = read_u32(&p); uint32_t W = read_u32(&p); uint32_t T = 0; for (uint32_t i = 0; i < H; ++i) { uint32_t s = 0; for (uint32_t j = 0; j < W; ++j) { s += read_u32(&p); } sums[i] = s; T += s; } /* 4桁出力テーブルを作る。 例えば dig4[123] はメモリ上で "0123"。 */ for (uint32_t i = 0; i < 10000; ++i) { uint32_t x = i; uint32_t a = x / 1000u; x -= a * 1000u; uint32_t b = x / 100u; x -= b * 100u; uint32_t c = x / 10u; uint32_t d = x - c * 10u; dig4[i] = (uint32_t)('0' + a) | ((uint32_t)('0' + b) << 8) | ((uint32_t)('0' + c) << 16) | ((uint32_t)('0' + d) << 24); lead4[i] = i >= 1000u ? 0 : i >= 100u ? 1 : i >= 10u ? 2 : 3; } /* 後ろから出力を作る。 10進変換を1桁ずつ /10 せず、 4桁ずつ /10000 する。 */ char *wp = outbuf + OUT_CAP; for (uint32_t i = H; i-- != 0;) { *--wp = '\n'; uint32_t v = sums[i] + T; uint32_t top; do { uint32_t q = v / 10000u; top = v - q * 10000u; wp -= 4; __builtin_memcpy(wp, &dig4[top], 4); v = q; } while (v != 0); /* 最上位4桁の不要な 0 を飛ばす */ wp += lead4[top]; } /* 全出力をほぼ1回の write で流す。 最大 10桁 + '\n' × 10^6 < 16MiB。 */ size_t left = (size_t)(outbuf + OUT_CAP - wp); while (left != 0) { ssize_t z = write(STDOUT_FILENO, wp, left); if (z <= 0) break; wp += z; left -= (size_t)z; } _exit(0); }