zoukankan      html  css  js  c++  java
  • JZYZOJ 2042 多项式逆元 NTT 多项式

    http://172.20.6.3/Problem_Show.asp?id=2042

    题意:求一个次数界为n的多项式在模P并模x^m的意义下的逆元。P=7*17*2^23+1。

    多项式逆元的含义以及求逆元的方法:http://blog.miskcoo.com/2015/05/polynomial-inverse

    公式推导一下。主要还是NTT的使用,我NTT写错了调了半天,太zz了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<complex>
     7 using namespace std;
     8 #define LL long long
     9 const LL P=(LL)7*17*(1<<23)+1;
    10 const int maxn=530010;
    11 LL a[maxn]={},b[maxn]={},e[maxn]={},zz[20][maxn]={};
    12 int bel[maxn]={};
    13 int bt,s,tot=0;
    14 LL mpow(LL x,LL k){
    15     if(k<0){x=mpow(x,P-2);k=-k;}
    16     LL z=1;
    17     while(k){
    18         if(k&1)z=(z*x)%P;
    19         x=(x*x)%P;
    20         k/=2;
    21     }return z;
    22 }
    23 inline void getit(){ for(int i=0;i<s;i++)bel[i]=((bel[i>>1]>>1)|((i&1)<<(bt-1))); }
    24 inline void ntt(LL *c,int n,int dft){
    25     for(int i=0;i<n;i++)if(bel[i]>i)swap(c[bel[i]],c[i]);
    26     for(int step=1;step<n;step<<=1){
    27         LL w=mpow(3,((P-1)/(step*2))*dft);
    28         for(int j=0;j<n;j+=(step<<1)){
    29             LL z=1;
    30             for(int i=j;i<j+step;++i){
    31                 LL x=c[i],y=(c[i+step]*z)%P;
    32                 c[i]=(x+y)%P;
    33                 c[i+step]=((x-y)%P+P)%P;
    34                 z=(z*w)%P;
    35             }
    36         }
    37     }
    38     if(dft==-1){
    39         LL mon=mpow(n,P-2);
    40         for(int i=0;i<n;i++)c[i]=(c[i]*mon)%P;
    41     }
    42 }
    43 inline void dontt(LL *c,LL *d,int x,int y){
    44     bt=1;s=2;int z=x+y-1;
    45     for(;s<z;++bt)s<<=1;
    46     getit();
    47     ntt(c,s,1);ntt(d,s,1);
    48     for(int i=0;i<s;i++)c[i]=(c[i]*d[i])%P;
    49     ntt(c,s,-1);ntt(d,s,1);
    50 }
    51 inline void doit(int n,int m){
    52     if(m==1){++tot; zz[tot][0]=mpow(a[0],P-2); return ;}
    53     doit(n,(m+1)/2);int siz=(m+1)/2; ++tot;
    54     for(int i=0;i<s;i++)e[i]=b[i]=bel[i]=0;
    55     for(int i=0;i<siz;i++){zz[tot][i]=(zz[tot-1][i]*2)%P;b[i]=zz[tot-1][i];}
    56     for(int i=min(n,m)-1;i>=0;--i)e[i]=a[i];
    57     dontt(zz[tot-1],b,siz,siz); siz=siz+siz-1;
    58     dontt(zz[tot-1],e,siz,min(n,m));
    59     for(int i=0;i<m;i++)zz[tot][i]=((zz[tot][i]-zz[tot-1][i])%P+P)%P;
    60 }
    61 int main(){
    62     //freopen("a.in","r",stdin);
    63     int n,m;scanf("%d%d",&n,&m);
    64     for(int i=0;i<n;i++){scanf("%lld",&a[i]);a[i]=((a[i]%P)+P)%P;}
    65     doit(n,m);
    66     for(int i=0;i<m;i++)printf("%lld ",zz[tot][i]);
    67     printf("
    ");
    68     return 0;
    69 }
    View Code

  • 相关阅读:
    JavaBean和Map之间的转化
    java基础Map遍历
    sql server
    android之使用百度地图(1)
    Java基础知识2(字符串)
    Java基础知识1
    DAY12-Java中的类--接DAY10
    DAY11-LocalDate小练习
    DAY10-万物皆对象-2018-2-2
    DAY9-字符串笔记整理2018-1-19
  • 原文地址:https://www.cnblogs.com/137shoebills/p/9164339.html
Copyright © 2011-2022 走看看