Module
#define L(x) (1 << (x))
const double PI = acos(-1.0);
const int N = 17, Maxn = L(N + 1);
double ax[Maxn], ay[Maxn], bx[Maxn], by[Maxn]
struct FFT
{
private :
int revv(int x, int bits) {
int ret = 0;
for (int i = 0; i < bits; i++) {
ret <<= 1;
ret |= x & 1;
x >>= 1;
}
return ret;
}
void fft(double * a, double * b, int n, bool rev)
{
int bits = 0;
while (1 << bits < n) ++bits;
for (int i = 0; i < n; i++)
{
int j = revv(i, bits);
if (i < j)
{
double t = a[i];
a[i] = a[j];
a[j] = t;
t = b[i];
b[i] = b[j];
b[j] = t;
}
}
for (int len = 2; len <= n; len <<= 1)
{
int half = len >> 1;
double wmx = cos(2 * PI / len);
double wmy = sin(2 * PI / len);
if (rev)
wmy = -wmy;
for (int i = 0; i < n; i += len)
{
double wx = 1;
double wy = 0;
for (int j = 0; j < half; j++)
{
double cx = a[i + j];
double cy = b[i + j];
double dx = a[i + j + half];
double dy = b[i + j + half];
double ex = dx * wx - dy * wy;
double ey = dx * wy + dy * wx;
a[i + j] = cx + ex;
b[i + j] = cy + ey;
a[i + j + half] = cx - ex;
b[i + j + half] = cy - ey;
double wnx = wx * wmx - wy * wmy;
double wny = wx * wmy + wy * wmx;
wx = wnx;
wy = wny;
}
}
}
if (rev)
{
for (int i = 0; i < n; i++)
{
a[i] /= n;
b[i] /= n;
}
}
}
public:
int solve(int a[],int na,int b[],int nb,long long ans[])
{
int len = max(na, nb), ln;
for(ln=0; L(ln)<len; ++ln);
len=L(++ln);
for (int i = 0; i < len ; ++i)
{
if (i >= na) ax[i] = 0, bx[i] =0;
else ax[i] = a[i], bx[i] = 0;
}
fft(ax, ay, len, 0);
for (int i = 0; i < len; ++i)
{
if (i >= nb) bx[i] = 0, by[i] = 0;
else bx[i] = b[i], by[i] = 0;
}
fft(bx, by, len, 0);
for (int i = 0; i < len; ++i)
{
double cx = ax[i] * bx[i] - ay[i] * by[i];
double cy = ax[i] * by[i] + ay[i] * bx[i];
ax[i] = cx, ay[i] = cy;
}
fft(ax, ay, len, 1);
for (int i = 0; i < len; ++i)
ans[i] = ax[i] + 0.01;
return len;
}
int solve(int a[], int na, long long ans[])
{
int len = na, ln;
for(ln = 0; L(ln) < na; ++ln);
len=L(++ln);
for(int i = 0;i < len; ++i)
{
if (i >= na) ax[i] = 0, ay[i] = 0;
else ax[i] = a[i], ay[i] = 0;
}
fft(ax, ay, len, 0);
for(int i=0;i<len;++i)
{
double cx = ax[i] * ax[i] - ay[i] * ay[i];
double cy = 2 * ax[i] * ay[i];
ax[i] = cx, ay[i] = cy;
}
fft(ax, ay, len, 1);
for(int i=0;i<len;++i)
ans[i] = ax[i] + 0.5;
return len;
}
};