Aleph1022 @ 2020-01-03 08:55:55
拆系数然后通过系数共轭得到点值表达,为什么 65 \kel \kel \kel
怀疑是精度问题
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1 << 18;
const long double pi = acos(-1);
const int W = 1 << 15;
int lena,lenb,mod,n;
int lg2[N + 5],rev[N + 5];
int ans[N + 5];
struct cp
{
long double a,b;
inline void operator+=(const cp &o)
{
a += o.a,b += o.b;
}
inline cp operator+(const cp &o) const
{
return (cp){a + o.a,b + o.b};
}
inline cp operator-(const cp &o) const
{
return (cp){a - o.a,b - o.b};
}
inline cp operator*(const cp &o) const
{
return (cp){a * o.a - b * o.b,a * o.b + b * o.a};
}
inline cp operator*(const double &o) const
{
return (cp){a * o,b * o};
}
inline cp operator~() const
{
return (cp){a,-b};
}
} f[N + 5],g[N + 5],h[N + 5],a[N + 5],b[N + 5],rt[N + 5];
inline void init(int len)
{
for(n = 1;n < len;n <<= 1);
for(register int i = 2;i <= n;++i)
lg2[i] = lg2[i >> 1] + 1;
cp w = (cp){cos(2 * pi / n),sin(2 * pi / n)};
rt[n >> 1] = (cp){1,0};
for(register int i = (n >> 1) + 1;i <= n;++i)
rt[i] = rt[i - 1] * w;
for(register int i = (n >> 1) - 1;i;--i)
rt[i] = rt[i << 1];
}
inline void fft(cp *a,int type,int n)
{
type == -1 && (reverse(a + 1,a + n),1);
int lg = lg2[n] - 1;
for(register int i = 0;i < n;++i)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << lg),
i < rev[i] && (swap(a[i],a[rev[i]]),1);
for(register int w = 2,m = 1;w <= n;w <<= 1,m <<= 1)
for(register int i = 0;i < n;i += w)
for(register int j = 0;j < m;++j)
{
cp t = rt[m | j] * a[i | j | m];
a[i | j | m] = a[i | j] - t,a[i | j] += t;
}
if(type == -1)
for(register int i = 0;i < n;++i)
a[i].a /= n,a[i].b /= n;
}
int main()
{
scanf("%d%d%d",&lena,&lenb,&mod),init(max(++lena,++lenb) << 1);
int x;
for(register int i = 0;i < lena;++i)
scanf("%d",&x),f[i] = (cp){x / W,x % W};
for(register int i = 0;i < lenb;++i)
scanf("%d",&x),g[i] = (cp){x / W,x % W};
fft(f,1,n),fft(g,1,n);
for(register int i = 0;i < n;++i)
h[i] = ~f[(n - i) % n];
for(register int i = 0;i < n;++i)
a[i] = f[i] * g[i],b[i] = g[i] * h[i];
fft(a,-1,n),fft(b,-1,n);
for(register int i = 0;i < n;++i)
{
long long ac = (a[i].a + b[i].a) / 2 + 0.5;
long long bd = b[i].a - ac + 0.5;
long long bcad = a[i].b + 0.5;
ans[i] = ((ac % mod * W % mod * W % mod) % mod + (bcad % mod * W % mod) % mod + bd % mod) % mod;
}
for(register int i = 0;i < lena + lenb - 1;++i)
printf("%d ",ans[i]);
}
by 神山识 @ 2020-01-03 08:57:01
qndjr
by 神山识 @ 2020-01-03 08:57:15
qndgxoi
by 雪颜 @ 2020-01-03 09:03:59
@alpha1022 我记得我WA50 -> 100就是改了输出的精度
by iostream @ 2020-01-03 09:42:37
每个单位根直接算应该可以,不要乘 w
by iostream @ 2020-01-03 09:43:12
for(int i=1;i<L>>1;i++)w[i+L/2]=Cp(cos(2*Pi*i/L),sin(2*Pi*i/L));
(我猜的)
by Aleph1022 @ 2020-01-03 09:53:07
@iostream 谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢
改了就过了 qwq
by pocafup @ 2020-01-03 11:23:41
%%%
by yummy @ 2020-01-03 12:00:27
Orz
by ImmortalWatcher @ 2020-01-09 16:44:57
THU二等的大佬你告诉我刚学OI??