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!

  • 相关阅读:
    mouse_event模拟鼠标滚轮
    润乾报表配置技术路线
    建筑 物件 开心背单词 读句子,单词,字母,看图例, 翻译,看动画
    文字过渡动画,曲线过渡动画,,使用这个插件assign shape keys
    运动锻炼 开心背单词 读句子,单词,字母,看图例, 翻译,看动画,学英语,轻松背单词,简单背单词
    blender293 内置插件 精度绘画控件,PDT学习003,pdt tangents 切线
    日常用品 背单词 读句子 看图片 读单词 读字母 翻译, 看动画 学英语
    blender293 内置插件 精度绘画控件,PDT学习 precision drawing tools
    乔布斯 背单词 02 读句子 单词 字母 翻译,看动画 学英语 名言 我菜顾我在,我菜故我在,blender加python
    狐狸 和 乌鸦 英语 朗读句子 背单词
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10659792.html
Copyright © 2011-2022 走看看