zoukankan      html  css  js  c++  java
  • 洛谷.3803.[模板]多项式乘法(NTT)

    题目链接:洛谷LOJ.

    为什么和那些差那么多啊。。

    在这里记一下原根

    Definition

      若(a,p)互质,且(p>1),我们称使(a^nequiv 1 (mod p))成立的最小正整数(n)(a)(p)的阶,记作(delta_p(a))
      例:(delta_7(2)=3)

    原根

      设(p)是正整数,(a)是整数,若(delta_p(a)=varphi(m)),则称(a)为模(p)的一个原根。
      从另一方面来说,若(g^i mod p eq g^j mod p (p为质数,i eq j且i,jinleft[1,p-1 ight])),则(g)(p)的原根。

    性质

      1. 若(p)有原根,那么(p)(varphi(varphi(p)))个原根。
      2. 有原根的数只有:(2,4,p^n,2 imes p^n) ((p)为奇素数,(n)为正整数)。
      3. 一个数的最小原根的大小是(O(n^{0.25}))的。
      4. 若(g)(p)的原根,则(g^a)(p)的原根的充要条件为 (a)(varphi(p))互质。
      (参考抄自这儿

    求法

      求(p)的原根:对(varphi(p)=p-1)分解质因子,即令(p-1=prod_{i=1}^kp_i^{a_i} (p_i为质数))
      若(g^{frac{p-1}{p_i}} eq 1 (mod p))恒成立,则(g)(p)的一个原根。


    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define P (998244353)
    #define G (3)
    #define inv_G (332748118)
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=(1<<21)+5;//2 097 152 //2e6+5;
    
    int n,m,rev[N];
    LL A[N],B[N],inv_lim;//全换成int好像大概略快吧 
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	register char c=gc();
    	for(;!isdigit(c);c=gc());
    	return c-'0';//233
    }
    inline LL FP(LL x,LL k)
    {
    	LL t=1;
    	for(; k; k>>=1,x=x*x%P)
    		if(k&1) t=t*x%P;
    	return t;
    }
    void NTT(LL *a,int lim,int type)
    {
    	for(int i=0; i<lim; ++i)
    		if(i<rev[i]) std::swap(a[i],a[rev[i]]);
    	for(int i=2; i<=lim; i<<=1)
    	{
    		int mid=i>>1;
    		LL Wn=FP(~type?G:inv_G,(P-1)/i),t,w;
    		for(int j=0; j<lim; j+=i)
    		{
    			LL w=1;
    			for(int k=0; k<mid; ++k, w=w*Wn%P)
    				a[j+k+mid]=(a[j+k]-(t=w*a[j+k+mid]%P)+P)%P,
    				a[j+k]=(a[j+k]+t)%P;
    		}
    	}
    	if(type==-1) for(int i=0; i<lim; ++i) a[i]=a[i]*inv_lim%P;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);//sb了拿那个read读n,m。。
    	for(int i=0; i<=n; ++i) A[i]=read();//(read()%P+P)%P
    	for(int i=0; i<=m; ++i) B[i]=read();
    	int lim=1,len=0;
    	while(lim<=n+m) lim<<=1,++len;
    	inv_lim=FP(lim,P-2);
    	for(int i=1; i<lim; ++i)
    		rev[i] = (rev[i>>1]>>1) | ((i&1)<<len-1);
    	NTT(A,lim,1), NTT(B,lim,1);
    	for(int i=0; i<lim; ++i) A[i]=A[i]*B[i]%P;
    	NTT(A,lim,-1);
    	for(int i=0; i<=n+m; ++i) printf("%lld ",A[i]);
    
    	return 0;
    }
    
  • 相关阅读:
    react-redux源码解析
    redux的源码解析
    react + dva + ant架构后台管理系统(一)
    fetch 代替 XMLHttpRequest (json-server 模拟后台接口)
    Es6 Generator函数
    java 的数据类型
    vue为app做h5页面,如何做到同域名对应不同版本的h5代码
    vue-devtools 的安装和使用
    jq源码解析之绑在$,jQuery上面的方法
    jquery的extend方法(源码解析)
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9153098.html
Copyright © 2011-2022 走看看