zoukankan      html  css  js  c++  java
  • 【LOJ6067】【2017 山东一轮集训 Day3】第三题 FFT

    【LOJ6067】【2017 山东一轮集训 Day3】第三题 FFT

    题目大意

      给你 (n,b,c,d,e,a_0,a_1,ldots,a_{n-1}),定义

    [egin{align} x_k&=b imes c^{4k}+d imes c^{2k}+e\ f(x)&=sum_{i=0}^{n-1}a_ix^i end{align} ]

      求 (f(x_0),f(x_1),ldots,f(x_{n-1}))

      对 ({10}^6+3) 取模。

    题解

      直接多项式多点求值(显然)会TLE。

      当 (c=0) 时:

    [egin{align} x_k&= egin{cases} b+d+e,&k=0\ e,&k eq 0\ end{cases} end{align} ]

      直接求就好了。

      当 (c eq 0,b=0) 时:

    [egin{align} f(x_k)&=sum_{i=0}^{n-1}a_i{(dc^{2k}+e)}^i\ &=sum_{i=0}^{n-1}a_isum_{j=0}^{i}{(dc^{2k})}^je^{i-j}inom{i}{j}\ &=sum_{j=0}^{n-1}frac{1}{j!}d^jc^{2kj}sum_{i=j}^{n-1}i!a_ie^{i-j}frac{1}{(i-j)!}\ &=sum_{j=0}^{n-1}frac{1}{j!}d^jc^{2kj}sum_{i=0}^{n-j-1}(n-i-1)!a_{n-i-1}e^{(n-i-1)-j}frac{1}{((n-i-1)-j)!}\ &=sum_{j=0}^{n-1}frac{1}{j!}d^jc^{2kj}g_j\ &=sum_{j=0}^{n-1}frac{1}{j!}d^jc^{k^2-({k-j)}^2+j^2}g_j\ &=c^{k^2}sum_{j=0}^{n-1}frac{1}{j!}d^jc^{j^2}g_jfrac{1}{c^{{(k-j)}^2}} end{align} ]

      当 (c eq 0,b eq 0) 时:

    [egin{align} bc^{4k}+dc^{2k}+e&=b(c^{4k}+frac{d}{b}c^{2k})+e\ &=b(c^{4k}+frac{d}{b}c^{2k}+{(frac{d}{2b})}^2-{(frac{d}{2b})}^2)+e\ &=b{(c^{2k}+frac{d}{2b})}^2-frac{d^2}{4b}+e\ &=b{(c^{2k}+d')}^2+e'\ end{align} ]

      然后用 (d')(e') 替换原来的 (d)(e)

    [egin{align} f(x_k)&=sum_{i=0}^{n-1}a_i{(b{(c^{2k}+d)}^2+e)}^i\ &=sum_{i=0}^{n-1}a_isum_{j=0}^{i}b^j{(c^{2k}+d)}^{2j}e^{i-j}inom{i}{j}\ &=sum_{j=0}^{n-1}b^j{(c^{2k}+d)}^{2j}frac{1}{j!}sum_{i=j}^{n-1}a_ii!e^{i-j}frac{1}{i-j}\ &=sum_{j=0}^{n-1}b^j{(c^{2k}+d)}^{2j}frac{1}{j!}g_j\ &=sum_{j=0}^{n-1}b^jfrac{1}{j!}g_jsum_{i=0}^{2j}c^{2ki}d^{2j-i}inom{2j}{i}\ &=sum_{i=0}^{2n-2}c^{2ki}frac{1}{i!}sum_{j=lceilfrac{i}{2} ceil}^{n-1}frac{(2j)!}{j!}b^jg_jfrac{1}{(2j-i)!}d^{2j-i}\ &=sum_{i=0}^{2n-2}c^{2ki}frac{1}{i!}sum_{2jgeq i}^{2n-2}frac{(2j)!}{j!}b^jg_jfrac{1}{(2j-i)!}d^{2j-i}\ &=sum_{i=0}^{2n-2}c^{2ki}frac{1}{i!}h_i\ &=c^{k^2}sum_{i=0}^{2n-2}frac{1}{i!}c^{i^2}h_ifrac{1}{c^{{(i-k)}^2}} end{align} ]

      那些卷积都可以FFT(任意模数FFT)。

      时间复杂度:(O(nlog n))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    #include<functional>
    #include<cmath>
    #include<vector>
    #include<assert.h>
    //using namespace std;
    using std::min;
    using std::max;
    using std::swap;
    using std::sort;
    using std::reverse;
    using std::random_shuffle;
    using std::lower_bound;
    using std::upper_bound;
    using std::unique;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef std::pair<int,int> pii;
    typedef std::pair<ll,ll> pll;
    void open(const char *s){
    #ifndef ONLINE_JUDGE
    	char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
    #endif
    }
    int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
    void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
    int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
    int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
    const ll p=1000003;
    const int N=530000;
    ll fp(ll a,ll b)
    {
    	if(!b)
    		return 1;
    	b=(b%(p-1)+p-1)%(p-1);
    	ll s=1;
    	for(;b;b>>=1,a=a*a%p)
    		if(b&1)
    			s=s*a%p;
    	return s;
    }
    namespace fft
    {
    	const int W=524288;
    	const ll M=1000;
    	typedef double db;
    	db pi=acos(-1);
    	struct cp
    	{
    		db x,y;
    		cp(db a=0,db b=0):x(a),y(b){}
    	};
    	cp operator +(cp a,cp b){return cp(a.x+b.x,a.y+b.y);}
    	cp operator -(cp a,cp b){return cp(a.x-b.x,a.y-b.y);}
    	cp operator *(cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
    	cp operator /(cp a,int b){return cp(a.x/b,a.y/b);}
    	cp conj(cp a){return cp(a.x,-a.y);}
    	cp muli(cp a){return cp(-a.y,a.x);}
    	cp divi(cp a){return cp(a.y,-a.x);}
    	int rev[N];
    	cp *w[20];
    	void fft(cp *a,int n,int t)
    	{
    		for(int i=1;i<n;i++)
    		{
    			rev[i]=(rev[i>>1]>>1)|(i&1?n>>1:0);
    			if(rev[i]>i)
    				swap(a[rev[i]],a[i]);
    		}
    		for(int i=2,s=1;i<=n;i<<=1,s++)
    			for(int j=0;j<n;j+=i)
    				for(int k=0;k<i/2;k++)
    				{
    					cp u=a[j+k];
    					cp v=a[j+k+i/2]*w[s][k];
    					a[j+k]=u+v;
    					a[j+k+i/2]=u-v;
    				}
    		if(t==-1)
    		{
    			reverse(a+1,a+n);
    			for(int i=0;i<n;i++)
    				a[i]=a[i]/n;
    		}
    	}
    	void dft(db *a,db *b,cp *c,cp *d,int n)
    	{
    		static cp a1[N],a2[N];
    		for(int i=0;i<n;i++)
    			a1[i]=cp(a[i],b[i]);
    		fft(a1,n,1);
    		for(int i=0;i<n;i++)
    			a2[i]=conj(a1[i]);
    		reverse(a2+1,a2+n);
    		for(int i=0;i<n;i++)
    		{
    			c[i]=(a1[i]+a2[i])/2;
    			d[i]=divi(a1[i]-a2[i])/2;
    		}
    	}
    	void idft(db *a,db *b,cp *c,cp *d,int n)
    	{
    		static cp a1[N];
    		for(int i=0;i<n;i++)
    			a1[i]=c[i]+muli(d[i]);
    		fft(a1,n,-1);
    		for(int i=0;i<n;i++)
    		{
    			a[i]=a1[i].x;
    			b[i]=a1[i].y;
    		}
    	}
    	void init()
    	{
    		for(int i=1;i<=19;i++)
    			w[i]=new cp[1<<(i-1)];
    		for(int i=0;i<W/2;i++)
    			w[19][i]=cp(cos(2*pi/W*i),sin(2*pi/W*i));
    		for(int i=18;i>=1;i--)
    			for(int j=0;j<1<<(i-1);j++)
    				w[i][j]=w[i+1][j<<1];
    	}
    	void mul(ll *a,ll *b,ll *c,int n,int m,int l)
    	{
    		static db a1[N],a2[N],b1[N],b2[N],c1[N],c2[N],d1[N],d2[N];
    		static cp a3[N],a4[N],b3[N],b4[N],c3[N],c4[N],d3[N],d4[N];
    		int k=1;
    		while(k<=n+m)
    			k<<=1;
    		for(int i=0;i<k;i++)
    			a1[i]=a2[i]=b1[i]=b2[i]=0;
    		for(int i=0;i<=n;i++)
    		{
    			a[i]=(a[i]+p)%p;
    			a1[i]=a[i]/M;
    			a2[i]=a[i]%M;
    		}
    		for(int i=0;i<=m;i++)
    		{
    			b[i]=(b[i]+p)%p;
    			b1[i]=b[i]/M;
    			b2[i]=b[i]%M;
    		}
    		dft(a1,a2,a3,a4,k);
    		dft(b1,b2,b3,b4,k);
    		for(int i=0;i<k;i++)
    		{
    			c3[i]=a3[i]*b3[i];
    			c4[i]=a3[i]*b4[i];
    			d3[i]=a4[i]*b3[i];
    			d4[i]=a4[i]*b4[i];
    		}
    		idft(c1,c2,c3,c4,k);
    		idft(d1,d2,d3,d4,k);
    		for(int i=0;i<=l;i++)
    			c[i]=((ll)(c1[i]+0.5)%p*M%p*M%p+(ll)(c2[i]+0.5)%p*M%p+(ll)(d1[i]+0.5)%p*M%p+(ll)(d2[i]+0.5)%p)%p;
    	}
    }
    int n;
    ll B,C,D,E;
    ll a[N];
    ll inv[N],fac[N],ifac[N];
    void init()
    {
    	inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;
    	for(int i=2;i<=200000;i++)
    	{
    		inv[i]=-p/i*inv[p%i]%p;
    		inv[i]=(inv[i]+p)%p;
    		fac[i]=fac[i-1]*i%p;
    		ifac[i]=ifac[i-1]*inv[i]%p;
    	}
    }
    namespace pregao
    {
    	ll b[N],c[N],s[N];
    	void gao()
    	{
    		for(int i=0;i<n;i++)
    		{
    			b[i]=a[n-i-1]*fac[n-i-1]%p;
    			c[i]=ifac[i]*fp(E,i)%p;
    		}
    		fft::mul(b,c,s,n-1,n-1,n-1);
    		reverse(s,s+n);
    	}
    }
    namespace gao1
    {
    	ll d[N],e[N],f[N],g[N],h[N],ans[N];
    	void gao()
    	{
    		pregao::gao();
    		for(int i=0;i<n;i++)
    		{
    			d[i]=pregao::s[i]*fp(D,i)%p*fp(C,(ll)i*i)%p*ifac[i]%p;
    			e[i]=fp(C,-(ll)i*i);
    		}
    		fft::mul(d,e,f,n-1,n-1,n-1);
    		reverse(d,d+n);
    		e[0]=0;
    		fft::mul(d,e,g,n-1,n-1,n-1);
    		for(int i=0;i<n;i++)
    		{
    			ans[i]=((f[i]+g[n-i-1])%p+p)%p;
    			ans[i]=ans[i]*fp(C,(ll)i*i)%p;
    		}
    		for(int i=0;i<n;i++)
    			printf("%lld
    ",ans[i]);
    	}
    }
    namespace gao2
    {
    	ll b[N],c[N],d[N],e[N],f[N],g[N],ans[N];
    	void gao()
    	{
    		E=(E-D*D%p*fp(4*B,p-2)%p+p)%p;
    		D=D*fp(2*B,p-2)%p;
    		pregao::gao();
    		for(int i=0;i<n;i++)
    			b[2*n-2*i-2]=fac[2*i]*ifac[i]%p*pregao::s[i]%p*fp(B,i)%p;
    		for(int i=0;i<2*n-1;i++)
    			c[i]=fp(D,i)*ifac[i]%p;
    		fft::mul(b,c,d,2*n-2,2*n-2,2*n-2);
    		reverse(d,d+2*n-1);
    		for(int i=0;i<2*n-1;i++)
    		{
    			d[i]=d[i]*ifac[i]%p*fp(C,(ll)i*i)%p;
    			e[i]=fp(C,-(ll)i*i);
    		}
    		fft::mul(d,e,f,n-1,n-1,n-1);
    		reverse(d,d+2*n-1);
    		e[0]=0;
    		fft::mul(d,e,g,2*n-2,2*n-2,2*n-2);
    		for(int i=0;i<n;i++)
    			ans[i]=(fp(C,(ll)i*i)*(f[i]+g[2*n-i-2])%p+p)%p;
    		for(int i=0;i<n;i++)
    			printf("%lld
    ",ans[i]);
    	}
    }
    namespace gao0
    {
    	void gao()
    	{
    		ll ans=0;
    		for(int i=n-1;i>=0;i--)
    		{
    			ans=ans*(E+B+D)%p;
    			ans=(ans+a[i])%p;
    		}
    		printf("%lld
    ",ans);
    		ans=0;
    		for(int i=n-1;i>=0;i--)
    		{
    			ans=ans*E%p;
    			ans=(ans+a[i])%p;
    		}
    		for(int i=1;i<n;i++)
    			printf("%lld
    ",ans);
    	}
    }
    int main()
    {
    	open("loj6067");
    	fft::init();
    	init();
    	scanf("%d%lld%lld%lld%lld",&n,&B,&C,&D,&E);
    	for(int i=0;i<n;i++)
    		a[i]=rd();
    	if(!C)
    		gao0::gao();
    	else if(!B)
    		gao1::gao();
    	else
    		gao2::gao();
    	return 0;
    }
    
  • 相关阅读:
    解决 搭建Jekins过程中 启动Tomcat的java.net.UnknownHostException异常
    射手和农场主
    java 和 JS(javaScript)中的反斜杠正则转义
    分享修改密码的SharePoint Web part: ITaCS Change Password web part
    分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机
    Office 365 的公共网站的一些限制及解决的办法
    SharePoint 2013 关闭 customErrors
    安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
    安装Office Web Apps Server 2013 – KB2592525安装失败
    如何将hyper-v虚拟机转换成vmware的虚拟机- 转换SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine (SP1)
  • 原文地址:https://www.cnblogs.com/ywwyww/p/9220869.html
Copyright © 2011-2022 走看看