题目链接:http://codeforces.com/gym/101480/attachments
mark一下O(1)快速乘,啥原理啊?还有这个长度计算,貌似也得好好学学啊?
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=1e6+3;
const int MAXN=1<<21;//玄学:开成两倍会有问题(1<<17=131072,1<<18=262144)
const int M=2e5+5;
ll qpow(ll a,ll b)
{
ll ret=1;
a%=MOD;
while(b)
{
if(b&1)
{
ret=ret*a%MOD;
}
a=(a*a)%MOD;
b>>=1;
}
return ret%MOD;
}
namespace NTT
{
typedef long long ll;
const ll MOD=1945555039024054273LL;
const ll g=5;
ll mul(ll x,ll y)
{
return (x*y-(ll)(x/(long double)MOD*y+1e-6)*MOD+MOD)%MOD;
}
ll qpow(ll a,ll k)
{
ll res=1LL;
while(k>0)
{
if(k&1)res=mul(res,a);
a=mul(a,a);
k>>=1;
}
return res;
}
void change(ll y[],int len)
{
for(int i=1,j=len/2;i<len-1;i++)
{
if(i<j)swap(y[i],y[j]);
int k=len/2;
while(j>=k)
{
j-=k;
k/=2;
}
if(j<k)j+=k;
}
}
void ntt(ll y[],int len,int on)
{
change(y,len);
for(int h=2;h<=len;h<<=1)
{
ll wn=qpow(g,(MOD-1)/h);
if(on==-1)wn=qpow(wn,MOD-2);
for(int j=0;j<len;j+=h)
{
ll w=1LL;
for(int k=j;k<j+h/2;k++)
{
ll u=y[k];
ll t=mul(w,y[k+h/2]);
y[k]=(u+t)%MOD;
y[k+h/2]=(u-t+MOD)%MOD;
w=mul(w,wn);
}
}
}
if(on==-1)
{
ll t=qpow(len,MOD-2);
for(int i=0;i<len;i++)
y[i]=mul(y[i],t);
}
}
void cal(ll x1[],ll x2[],ll tot)
{
int len=1;
while(len<2*tot)len<<=1;
ntt(x1,len,1);
ntt(x2,len,1);
for(int i=0;i<len;i++)
x1[i]=mul(x1[i],x2[i]);
ntt(x1,len,-1);
}
}
ll A[M],B[M];
ll fact[M*2],inv[M*2];
ll F1[MAXN],F2[MAXN],res[MAXN];
void init()
{
fact[0]=1;
inv[0]=1;
for(int i=1;i<M*2;i++)
fact[i]=fact[i-1]*i%MOD;
for(int i=1;i<M*2;i++)
inv[i]=qpow(fact[i],MOD-2);
}
ll C(ll n,ll m)
{
return fact[n]*inv[m]%MOD*inv[n-m]%MOD;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
init();
int n;
ll a,b,c;
ll ans=0;
scanf("%d%lld%lld%lld",&n,&a,&b,&c);
for(int i=1;i<=n;i++)
scanf("%lld",&A[i]);
for(int i=1;i<=n;i++)
scanf("%lld",&B[i]);
for(int i=2;i<=n;i++)
{
ans=(ans+C(n-1+n-i-1,n-i)*qpow(b,n-1)%MOD*qpow(a,n-i)%MOD*B[i]%MOD)%MOD;
ans=(ans+C(n-1+n-i-1,n-i)*qpow(b,n-i)%MOD*qpow(a,n-1)%MOD*A[i]%MOD)%MOD;
}
for(int i=2;i<=n;i++)
{
F1[i]=qpow(b,n-i)*inv[n-i]%MOD;
F2[i]=qpow(a,n-i)*inv[n-i]%MOD;
}
NTT :: cal(F1,F2,n+1);
for(int i=0;i<=2*n;i++)
{
F1[i]%=MOD;
ans=(ans+fact[2*n-i]*F1[i]%MOD*c%MOD)%MOD;
}
printf("%lld\n",ans);
return 0;
}