// hint::UINT_64 tmp = stoui64<DIGIT>(buffer + pos - DIGIT);
hint::UINT_32 tmp = stobase10000(buffer + pos - DIGIT);
comary[i].imag(tmp);
i++;
pos -= DIGIT;
}
if (pos > 0)
{
hint::UINT_32 tmp = stoui64(buffer, pos);
comary[i].imag(tmp);
}
return len;
}
inline void num_to_s(char *s, UINT_64 num)
{
char c = '0';
int i = DIGIT;
while (i > 0)
{
i--;
std::tie(num, c) = div_mod<UINT_64>(num, 10);
s[i] = c + '0';
}
}
constexpr void num_to_s_base10000(char *s, UINT_32 num)
{
s[3] = '0' + num % 10;
s[2] = '0' + num / 10 % 10;
s[1] = '0' + num / 100 % 10;
s[0] = '0' + num / 1000 % 10;
}
constexpr void num_to_s_base100000(char *s, UINT_32 num)
{
s[4] = '0' + num % 10;
s[3] = '0' + num / 10 % 10;
s[2] = '0' + num / 100 % 10;
s[1] = '0' + num / 1000 % 10;
s[0] = '0' + num / 10000 % 10;
}
class ItoStrBase10000
{
private:
uint32_t table[10000]{};
public:
static constexpr uint32_t itosbase10000(uint32_t num)
{
uint32_t res = '0' * 0x1010101;
res += (num / 1000 % 10) | ((num / 100 % 10) << 8) |
((num / 10 % 10) << 16) | ((num % 10) << 24);
return res;
}
constexpr ItoStrBase10000()
{
for (size_t i = 0; i < 10000; i++)
{
table[i] = itosbase10000(i);
}
}
void tostr(char *str, uint32_t num) const
{
*reinterpret_cast<uint32_t *>(str) = table[num];
}
uint32_t tostr(uint32_t num) const
{
return table[num];
}
};
}
using namespace std;
using namespace hint;
using namespace hint_transform;
using namespace hint_fft;
int main()
{
constexpr size_t STR_LEN = 2000008;
constexpr uint64_t BASE = hint::qpow(10ull, DIGIT);
static constexpr ItoStrBase10000 transfer;
static AlignAry<char, STR_LEN> out;
static AlignAry<HintFloat, 1 << 20> fft_ary_avx;
Complex *fft_ary = fft_ary_avx.template cast_ptr<Complex>();
uint32_t *ary = out.template cast_ptr<uint32_t>();
size_t len_a = 0, len_b = 0;
fread(out.data(), 1, STR_LEN, stdin);
char *p = out.data();
/*
struct stat sb;
int fd = fileno(stdin);
fstat(fd, &sb);
p = (char *)mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
madvise(p, sb.st_size, MADV_SEQUENTIAL);
*/
while (p[len_a] >= '0')
{
len_a++;
}
if (len_a == 1 && p[0] == '0')
{
puts("0");
return 0;
}
char *b = p + len_a;
while (!isdigit(*b))
{
b++;
}
while (b[len_b] >= '0')
{
len_b++;
}
if (len_b == 1 && b[0] == '0')
{
puts("0");
return 0;
} // 0.46ms
size_t len1 = char_to_real(p, fft_ary, len_a);
size_t len2 = char_to_imag(b, fft_ary, len_b); // 1.67ms
size_t fft_len = int_ceil2(len1 + len2 - 1);
small_fft.dif_avx(fft_ary, fft_len);
HintFloat inv = -0.5 / fft_len;
const Complex2 invx4(inv);
for (size_t i = 0; i < fft_len; i += 2)
{
Complex2 tmp = fft_ary + i;
tmp = tmp.square().linear_mul(invx4);
(tmp.conj()).store(fft_ary + i);
}
small_fft.dit_avx(fft_ary, fft_len); // 6ms
UINT_64 carry = 0;
size_t pos = STR_LEN / 4 - 1;
for (size_t i = 0; i < len1 + len2 - 1; i++)
{
carry += UINT_64(fft_ary[i].imag() + 0.5);
UINT_64 num = 0;
std::tie(carry, num) = div_mod<UINT_64>(carry, BASE);
ary[pos] = transfer.tostr(num);
pos--;
}
ary[pos] = transfer.tostr(carry);
pos *= 4;
while (out[pos] == '0')
{
pos++;
} // 0.8ms
fwrite(out.data() + pos, 1, STR_LEN - pos, stdout);
}
Compilation | N/A | N/A | Compile Error | Score: N/A | 显示更多 |