zoukankan      html  css  js  c++  java
  • 多项式幂函数(加强版)

    传送门

    Solution

    对于问题(B(x)=A^k(x) mod x^n)

    我们有一个既定的式子

    [B(x)=e^{kln(A(x))} ]

    如果此时不保证(a_0=1),那么就不能保证([kln(A(x))](0)=0),在求exp的时候,就会很麻烦

    解决办法是,我们设(a_tx^t)是多项式的(A)的次数最小的项

    那么直接将原来的多项式除去(a_tx^t),最后求完exp后再乘回(a_t^kx^{tk})即可

    实践的时候,发现如果直接套用原来的模板,求出来的恰好就是((frac{A(x)}{a_tx^t})^k)

    虽然不知道为什么,感觉怎么也证明不出来,貌似是有问题的吧

    还是先把原式都除以(a_tx^t)再算比较靠谱些


    Code 

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define reg register
    const int N=1<<18|5,P=998244353,g=3,invg=332748118;
    inline int read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x*10ll+ch-'0')%P;ch=getchar();}
    	return x*f;
    }
    #define Mul(x,y) (1ll*(x)*(y)%P)
    #define ri reg int i
    int _[N],pos[N];
    int fpow(int x,int m){int r=1;for(;m;m>>=1,x=Mul(x,x))if(m&1)r=Mul(r,x);return r;}
    void der(int *a,int *b,int n){for(ri=0;i<n-1;++i) b[i]=Mul(i+1,a[i+1]);b[n-1]=0;}
    void inte(int *a,int *b,int n)
    {
    	ri;for(_[1]=i=1;i<n;++i,_[i]=Mul(_[P%i],P-P/i));
    	for(i=n-1;i;--i)b[i]=Mul(a[i-1],_[i]);b[0]=0;
    }
    void init(int len)
    {
    	reg int i;
    	for(i=0;i<len;++i) pos[i]=(pos[i>>1]>>1)|((i&1)*(len>>1));
    }
    void NTT(int *a,int n,int type)
    {
    	register int i,j,k,w,wn,X,Y;
    	for(i=0;i<n;++i) if(i<pos[i]) swap(a[i],a[pos[i]]);
    	for(i=1;i<n;i<<=1)
    	{
    		wn=fpow(type>0?g:invg,(P-1)/(i<<1));
    		for(j=0;j<n;j+=i<<1)for(w=1,k=0;k<i;++k,w=Mul(w,wn))
    		{
    			X=a[j+k],Y=Mul(w,a[j+k+i]);
    			a[j+k]=(X+Y)%P;a[j+k+i]=(X-Y+P)%P;
    		}
    	}
    	reg int invn=fpow(n,P-2);
    	if(type==-1)for(i=0;i<n;++i)a[i]=Mul(a[i],invn);
    }
    void Comb(int *a,int *b,int *c,int n)
    {
    	static int A[N],B[N],len;
    	for(len=1;len<(n<<1);len<<=1);
    	memcpy(A,a,sizeof(int[n]));memcpy(B,b,sizeof(int[n]));
    	memset(A+n,0,sizeof(int[len-n]));memset(B+n,0,sizeof(int[len-n]));
    	reg int i;init(len);NTT(A,len,1);NTT(B,len,1);
    	for(i=0;i<len;++i) c[i]=Mul(A[i],B[i]);NTT(c,len,-1);
    	memset(c+n,0,sizeof(int[len-n]));
    }
    void _I(int *A,int *b,int n)
    {
    	if(n==1) return(void)(b[0]=fpow(A[0],P-2));
    	int t=(n+1)>>1;_I(A,b,t);
    	static int a[N],len;
    	for(len=1;len<(n<<1);len<<=1);
    	memcpy(a,A,sizeof(int[n]));memset(a+n,0,sizeof(int[len-n]));
    	memset(b+t,0,sizeof(int[len-t]));init(len);
    	reg int i;NTT(a,len,1);NTT(b,len,1);
    	for(i=0;i<len;++i)b[i]=(Mul(2ll,b[i])-Mul(a[i],Mul(b[i],b[i]))+P)%P;
    	NTT(b,len,-1);memset(b+n,0,sizeof(int[len-n]));
    }
    void Inv(int *A,int *b,int n)
    {
    	static int a[N];
    	memcpy(a,A,sizeof(int[n]));
    	_I(a,b,n);
    }
    void ln(int *A,int *B,int n)
    {
    	static int a[N],da[N];
    	memcpy(a,A,sizeof(int[n]));memcpy(da,A,sizeof(int[n]));
    	Inv(a,a,n);der(da,da,n);Comb(da,a,B,n);inte(B,B,n);
    }
    void _e(int *a,int *b,int n)
    {
    	if(n==1)return(void)(b[0]=1);
    	int t=(n+1)>>1;_e(a,b,t);
    	static int xxx[N];
    	ln(b,xxx,n);reg int i;
    	for(i=0;i<n;++i)xxx[i]=(-xxx[i]+a[i]+P)%P;
    	xxx[0]=(xxx[0]+1)%P;
    	Comb(b,xxx,b,n);
    }
    void exp(int *A,int *b,int n)
    {
    	static int a[N];
    	memcpy(a,A,sizeof(int[n]));
    	_e(a,b,n);
    }
    int A[N],xxx[N],B[N],n,k;
    int main()
    {
    	n=read();k=read();
    	reg int i,zero=0,x,K;bool flag=false;
    	for(i=0;i<n;++i)
    	{
    		x=read();
    		!(x||flag)?++zero:flag=true,A[i-zero]=x;
    	}
    	if(!flag)
    	{
    		for(i=0;i<n;++i) putchar('0'),putchar(' ');
    		return 0;
    	}
    	K=fpow(A[0],k);
    	for(i=0;i<n-zero;++i) A[i]=Mul(A[i],K);
    	ln(A,xxx,n-zero);
    	for(i=0;i<n-zero;++i) xxx[i]=Mul(xxx[i],k);
    	exp(xxx,B,n-zero);zero=Mul(zero,k);
    	for(i=0;i<min(zero,n);++i) putchar('0'),putchar(' ');
    	for(i=zero;i<n;++i) printf("%d ",Mul(B[i-zero],K));
    	return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    简单站内HTML文件搜索程序
    用 PHP 使 Web 数据分析进入更高境界
    半小时教你学会正则表达式
    如何使用php开发高效的WEB系统
    PHP6将实现的几个特性/功能
    用php定制404错误页面,并发信给管理员的程序
    实用技巧:PHP截取中文字符串的问题
    Windows XP下全新安装Apache2,PHP5,MYSQL5,Zend的简单过程
    网络流—最大流(EdmondKarp算法)
    poj 1094 Sorting It All Out(拓扑排序)
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10659792.html
Copyright © 2011-2022 走看看