zoukankan      html  css  js  c++  java
  • bzoj2194 快速傅立叶之二 ntt

    bzoj2194 快速傅立叶之二

    链接

    bzoj

    思路

    对我这种和式不强的人,直接转二维看。
    发现对(C_k)贡献的数对(i,j),都是右斜对角线。
    既然贡献是对角线,我们可以利用对角线的性质了。
    不过右斜角线不太好,我们把每一行都reverse一下,换成左斜角线。
    对角线上(i+j)相等,可以套上多项式乘法了。

    隐藏bug

    (a_i,b_i)均不大于100,而且数字有1e5个
    最大值是1e9,而模数是998244353
    应该是可以卡掉模数的,但是不故意卡是不可能爆模数的。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=4e5+7,mod=998244353;
    int read() {
    	int x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    int n,a[N],b[N],limit=1,l,r[N];
    int q_pow(int a,int b) {
    	int ans=1;
    	while(b) {
    		if(b&1) ans=1LL*ans*a%mod;
    		a=1LL*a*a%mod;
    		b>>=1;
    	}
    	return ans;
    }
    void ntt(int *a,int type) {
    	for(int i=0;i<=limit;++i)
    		if(i<r[i]) swap(a[i],a[r[i]]);
    	for(int mid=1;mid<limit;mid<<=1) {
    		int Wn=q_pow(3,(mod-1)/(mid<<1));
    		for(int i=0;i<limit;i+=(mid<<1)) {
    			for(int j=0,w=1;j<mid;++j,w=1LL*w*Wn%mod) {
    				int x=a[i+j],y=1LL*w*a[i+j+mid]%mod;
    				a[i+j]=(x+y)%mod;
    				a[i+j+mid]=(x+mod-y)%mod;
    			}
    		}
    	}
    	if(type==-1) {
    		reverse(&a[1],&a[limit]);
    		int inv=q_pow(limit,mod-2);
    		for(int i=0;i<=limit;++i) a[i]=1LL*a[i]*inv%mod;
    	}
    }
    int main() {
    	int n=read()-1;
    	for(int i=0;i<=n;++i) a[n-i+1]=read(),b[i]=read();
    	while(limit<=n+n) limit<<=1,l++;
    	for(int i=0;i<=limit;++i)
    		r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	ntt(a,1),ntt(b,1);
    	for(int i=0;i<=limit;++i) a[i]=1LL*a[i]*b[i]%mod;
    	ntt(a,-1);
    	for(int i=n+1;i>=1;--i) printf("%d
    ",a[i]);
    	return 0;
    }
    
  • 相关阅读:
    MVC学习中遇到问题
    静态类和单例模式区别
    类或方法名后加<>
    MVC5入门
    开发BI系统时的需求分析研究
    BI项目需求分析书-模板
    商业智能学习系统
    数据库设计三大范式[转]
    BW对应后台表[转]
    SQL优化方案
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10697399.html
Copyright © 2011-2022 走看看