hdu 4656(NTT

传送门

Evaluation

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 211    Accepted Submission(s): 64


Problem Description
x k=b*c (2k)+d
F(x)=a 0 x 0+a 1 x 1+a 2 x 2+...+a n-1 x n-1
Given n, b, c, d, a 0, ..., a n-1, calculate F(x 0), ..., F(x n-1).
 

Input
There is only one test case. 
First line, four integers, n, b, c, d. 
Second line, n integers, a 0, ..., a n-1

1<=n<=10 5
1<= b, c, d <=10 6
0<=a i<=10 6
 

Output
n lines. i-th line contains one integer,  F(xi-1)
Since the answers may be very large, you should output them modulo 10 6+3.
 

Sample Input
  
  
2 1 2 3 0 1
 

Sample Output
  
  
4 7
 

Source
 

Recommend
zhuyuanchen520   |   We have carefully selected several similar problems for you:   6170  6169  6168  6167  6166 

//china no.1
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <stdio.h>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <sstream>
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <bitset>
#include <complex>
using namespace std;

#define pi acos(-1)
#define PI acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x,y) memset(x,y,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
#define FOR(x,n,i) for(int i=x;i<=n;i++)
#define FOr(x,n,i) for(int i=x;i<n;i++)
#define W while
#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
#define bug printf("***********\n");
#define db double
#define ll long long
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,1,-1,-1,1};
const int dy[]={0,1,0,-1,-1,1,-1,1};
const int maxn=1e3+10;
const int maxx=1e5+10;
const double EPS=1e-8;
const double eps=1e-8;
const LL mod=1e6+3;
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
template <class T>
inline bool scan_d(T &ret){char c;int sgn;if (c = getchar(), c == EOF){return 0;}
while (c != '-' && (c < '0' || c > '9')){c = getchar();}sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0' && c <= '9'){ret = ret * 10 + (c - '0');}ret *= sgn;return 1;}

inline bool scan_lf(double &num){char in;double Dec=0.1;bool IsN=false,IsD=false;in=getchar();if(in==EOF) return false;
while(in!='-'&&in!='.'&&(in<'0'||in>'9'))in=getchar();if(in=='-'){IsN=true;num=0;}else if(in=='.'){IsD=true;num=0;}
else num=in-'0';if(!IsD){while(in=getchar(),in>='0'&&in<='9'){num*=10;num+=in-'0';}}
if(in!='.'){if(IsN) num=-num;return true;}else{while(in=getchar(),in>='0'&&in<='9'){num+=Dec*(in-'0');Dec*=0.1;}}
if(IsN) num=-num;return true;}

void Out(LL a){if(a < 0) { putchar('-'); a = -a; }if(a >= 10) Out(a / 10);putchar(a % 10 + '0');}
void print(LL a){ Out(a),puts("");}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
//cerr << "run time is " << clock() << endl;

const LL P1=998244353LL,P2=1004535809LL,E1=334257240187163831LL,
E2=668514958533372747LL;
const LL P=1002772198720536577LL,g=3;///费马素数
const int N=1e5+5,M=524300;
int inv[mod+5],fac[N],q[N],p[N<<1],a[N],x1[M],x2[M],_wn[30],w1[M],w2[M];
int n,b,c,d;
///_wn[i] ///原根的2^0 至2^21的幂
LL mulmod(LL x,LL y)
{
    LL tmp=(x*y-(LL)((long double)x/P*y+0.5)*P);
    return tmp<0?tmp+P:tmp;
}
inline int CRT(LL a1,LL a2)
{
    LL t=(mulmod(a1,E1)+mulmod(a2,E2))%P;
    if(t<0) t+=P;
    return t%mod;
}

long long q_pow(long long x,long long y,long long z)
{
    long long ans=1;
    while(y>0)
    {
        if(y&1)ans=ans*x%z;
        x=x*x%z;
        y>>=1;
    }
    return ans;
}

void NTT(int *A,int len,int on,int P)
{
    int i,j=len>>1,k,l,w,wn,c=0,u,v;/// j 模拟二进制反转进位的的位置
    for(i=1;i<len-1;i++)
    {
        if(i<j) swap(A[i],A[j]);
        for(k=len>>1;(j^=k)<k;k>>=1);
    }
    for(i=0;i<=21;i++) _wn[i]=q_pow(3,P-1>>i,P);
    for(l=2;l<=len;l<<=1)
    {
        i=l>>1,wn=_wn[++c];
        for(j=0;j<len;j+=l)
        {
            w=1;
            for(k=j;k<j+i;k++)
            {
                u=A[k],v=(LL)A[k+i]*w%P;///蝶型操作
                A[k]=(u+v)%P,A[k+i]=(u-v+P)%P;
                w=(LL)w*wn%P;
            }
        }
    }
    if(on==-1)///插值
    {
        int inv_len=q_pow(len,P-2,P);///逆元
        for(int i=0;i<len;i++) A[i]=(LL)A[i]*inv_len%P;
        for(int i=1;i<len/2;i++) swap(A[i],A[len-i]);
    }
}


void work(int *x,int *y,int len,int n)///卷积,点乘,插值
{
    memcpy(w1,x,len<<2);
    memcpy(w2,y,len<<2);
    NTT(w1,len,1,P1);NTT(w2,len,1,P1);
    for(int i=0;i<len;i++) w1[i]=(LL)w1[i]*w2[i]%P1;
    NTT(w1,len,-1,P1);
    NTT(x,len,1,P2);NTT(y,len,1,P2);
    for(int i=0;i<len;i++) x[i]=(LL)x[i]*y[i]%P2;
    NTT(x,len,-1,P2);
    for(int i=0;i<n;i++) p[i]=CRT(w1[i],x[i]);
}

int get_len(int n)///计算刚好比n大的2的N次幂
{
    int len=1;
    W(len<=n<<1) len<<=1;
    return len;
}

int main()
{
    inv[1]=fac[0]=fac[1]=1;
    scan_d(n);scan_d(b);scan_d(c);scan_d(d);
    FOr(0,n,i)
        scan_d(a[i]);
    for(int i=2;i<=n;i++)
    {
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
        /*
        mod=ki+r
        i=-r/k%mod
        1/i=-(mod/k)/r%mod
        1/i=(mod-(mod/k))/r%mod
        */
        fac[i]=(LL)fac[i-1]*i%mod;
    }
    for(int i=n+1;i<1000003;i++)
    {
        inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
    }
    int len=1;
    len=get_len(n);
    LL t=1;
    for(int i=0;i<n;i++,t=t*d%mod)
    {
        x1[i]=(LL)(a[n-1-i])*fac[n-1-i]%mod;//i!*a_i
        x2[i]=t*inv[fac[i]]%mod;//(i-j)!^-1*d^i
    }
    work(x1,x2,len,n);
    t=1;
    reverse(p,p+n);
    for(int i=0;i<n;i++,t=t*b%mod)
    {
        q[i]=q_pow(c,(LL)i*i%(mod-1),mod);//c^(j^2)
        x1[i]=t*q[i]%mod*(LL)p[i]%mod*inv[fac[i]]%mod;
        //(j!)^-1 * b^j * p[j] * c^(j^2)
        x2[n-1-i]=x2[n-1+i]=inv[q[i]];
        // c^(-j^2)
    }
    len<<=1;
    for(int i=n;i<n<<1;i++) x1[i]=0;
    for(int i=2*n-1;i<len;i++) x1[i]=x2[i]=0;
    work(x1,x2,len,n<<1);
    for(int i=0;i<n;i++)
    {
        print((LL)p[n-1+i]*q[i]%mod);
    }
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值