• 洛谷P4512 【模板】多项式除法


    https://www.luogu.org/problemnew/show/P4512

    题解:http://picks.logdown.com/posts/197262-polynomial-division

    备份

    用系数反转消去余数?不知道怎么想出来的方法。。

    版本1:基于版本2,要求n>=m

      1 #prag
      2 ma GCC optimize(2)
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<cmath>
      8 using namespace std;
      9 #define fi first
     10 #define se second
     11 #define mp make_pair
     12 #define pb push_back
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 const int md=998244353;
     16 const int N=262144;
     17 #define delto(a,b) ((a)-=(b),((a)<0)&&((a)+=md))
     18 inline int del(int a,int b)
     19 {
     20     a-=b;
     21     return a<0?a+md:a;
     22 }
     23 int rev[N];
     24 void init(int len)
     25 {
     26     int bit=0,i;
     27     while((1<<(bit+1))<=len)    ++bit;
     28     for(i=1;i<len;++i)
     29         rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
     30 }
     31 ull poww(ull a,ull b)
     32 {
     33     ull ans=1;
     34     for(;b;b>>=1,a=a*a%md)
     35         if(b&1)
     36             ans=ans*a%md;
     37     return ans;
     38 }
     39 int inv[300011];
     40 void dft(int *a,int len,int idx)//要求len为2的幂
     41 {
     42     int i,j,k,t1,t2;ull wn,wnk;
     43     for(i=0;i<len;++i)
     44         if(i<rev[i])
     45             swap(a[i],a[rev[i]]);
     46     for(i=1;i<len;i<<=1)
     47     {
     48         wn=poww(idx==1?3:332748118,(md-1)/(i<<1));
     49         for(j=0;j<len;j+=(i<<1))
     50         {
     51             wnk=1;
     52             for(k=j;k<j+i;++k,wnk=wnk*wn%md)
     53             {
     54                 t1=a[k];t2=a[k+i]*wnk%md;
     55                 a[k]+=t2;
     56                 (a[k]>=md)&&(a[k]-=md);
     57                 a[k+i]=t1-t2;
     58                 (a[k+i]<0)&&(a[k+i]+=md);
     59             }
     60         }
     61     }
     62     if(idx==-1)
     63     {
     64         ull ilen=inv[len];
     65         for(i=0;i<len;++i)
     66             a[i]=a[i]*ilen%md;
     67     }
     68 }
     69 void p_inv(int *f,int *g,int len)//g=f^(-1);f,g数组的长度不小于2len(需要足够长用于临时存放元素);要求len是2的幂
     70 {
     71     static int t1[N],t2[N];
     72     g[0]=poww(f[0],md-2);
     73     for(int i=2,j;i<=len;i<<=1)
     74     {
     75         memcpy(t1,f,sizeof(int)*i);
     76         memcpy(t2,g,sizeof(int)*(i>>1));
     77         memset(t2+(i>>1),0,sizeof(int)*(i>>1));
     78         init(i);
     79         dft(t1,i,1);dft(t2,i,1);
     80         for(j=0;j<i;++j)
     81             t1[j]=ull(t1[j])*t2[j]%md;
     82         dft(t1,i,-1);
     83         for(j=0;j<(i>>1);++j)
     84             t1[j]=t1[j+(i>>1)];
     85         memset(t1+(i>>1),0,sizeof(int)*(i>>1));
     86         dft(t1,i,1);
     87         for(j=0;j<i;++j)
     88             t1[j]=ull(t1[j])*t2[j]%md;
     89         dft(t1,i,-1);
     90         for(j=i>>1;j<i;++j)
     91             g[j]=md-t1[j-(i>>1)];
     92     }
     93 }
     94 inline void p_de(int *f,int len)//derivative求导;f=f'
     95 {
     96     for(int i=0;i<len-1;++i)
     97         f[i]=ull(i+1)*f[i+1]%md;
     98     f[len-1]=0;
     99 }
    100 inline void p_in(int *f,int len)//integral积分;f=?f
    101 {
    102     for(int i=len-1;i>=1;--i)
    103         f[i]=ull(f[i-1])*inv[i]%md;
    104     f[0]=0;
    105 }
    106 void p_ln(int *f,int len)//要求len为2的幂,f[0]=1
    107 {
    108     static int t3[N];
    109     p_inv(f,t3,len);p_de(f,len);
    110     init(len<<1);
    111     dft(f,len<<1,1);dft(t3,len<<1,1);
    112     for(int i=0;i<(len<<1);++i)
    113         f[i]=ull(f[i])*t3[i]%md;
    114     dft(f,len<<1,-1);p_in(f,len);
    115 }
    116 void p_exp(int *f,int *g,int len)//要求len为2的幂,f[0]=0
    117 {
    118     static int t1[N],t2[N];
    119     g[0]=1;
    120     for(int i=2,j;i<=len;i<<=1)
    121     {
    122         memcpy(t1,g,sizeof(int)*(i>>1));
    123         memset(t1+(i>>1),0,sizeof(int)*(i>>1));
    124         p_ln(t1,i);
    125         for(j=0;j<(i>>1);++j)
    126             t1[j]=del(f[j+(i>>1)],t1[j+(i>>1)]);
    127         memset(t1+(i>>1),0,sizeof(int)*(i>>1));
    128         init(i);
    129         dft(t1,i,1);
    130         memcpy(t2,g,sizeof(int)*(i>>1));
    131         memset(t2+(i>>1),0,sizeof(int)*(i>>1));
    132         dft(t2,i,1);
    133         for(j=0;j<i;++j)
    134             t1[j]=ull(t1[j])*t2[j]%md;
    135         dft(t1,i,-1);
    136         for(j=i>>1;j<i;++j)
    137             g[j]=t1[j-(i>>1)];
    138     }
    139 }
    140 void p_div(int *a,int *b,int *c,int n,int m)//c=a/b;deg(a)=n,deg(b)=m,deg(c)=n-m;a,b无前导0;n>=m
    141 {
    142     reverse(a,a+n+1);reverse(b,b+m+1);
    143     int x=n-m+1,t=1;
    144     for(;t<x;t<<=1);
    145     memset(b+m+1,0,sizeof(int)*max(t-m-1,0));
    146     p_inv(b,c,t);
    147     memset(c+x,0,sizeof(int)*((t<<1)-x));
    148     memset(a+x,0,sizeof(int)*((t<<1)-x));
    149     init(t<<1);
    150     dft(a,t<<1,1);dft(c,t<<1,1);
    151     for(int i=0;i<(t<<1);++i)
    152         c[i]=ull(c[i])*a[i]%md;
    153     dft(c,t<<1,-1);
    154     memset(c+(n-m+1),0,sizeof(int)*((t<<1)-n+m-1));
    155     reverse(c,c+x);
    156 }
    157 void p_divmod(int *a,int *b,int *c,int *d,int n,int m)//c=a/b,d=a%b,deg(d)=(<=)m-1;其余同上
    158 {
    159     static int t1[N];
    160     memcpy(d,a,sizeof(int)*(m+1));
    161     int x=n+1,t=1;
    162     for(;t<x;t<<=1);
    163     memcpy(t1,b,sizeof(int)*(m+1));
    164     memset(t1+m+1,0,sizeof(int)*max(t-m-1,0));
    165     p_div(a,b,c,n,m);
    166     memcpy(a,c,sizeof(int)*(n-m+1));
    167     memset(a+n-m+1,0,sizeof(int)*(t-n+m-1));
    168     init(t);
    169     dft(a,t,1);dft(t1,t,1);
    170     for(int i=0;i<t;++i)
    171         t1[i]=ull(t1[i])*a[i]%md;
    172     dft(t1,t,-1);
    173     for(int i=0;i<=m;++i)
    174         delto(d[i],t1[i]);
    175 }
    176 int a[N],b[N],c[N],d[N];
    177 int n,m;
    178 //int a1[N],b1[N],c1[N],d1[N];
    179 int main()
    180 {
    181     int i;
    182     inv[1]=1;
    183     for(i=2;i<=300000;++i)
    184         inv[i]=ull(md-md/i)*inv[md%i]%md;
    185     scanf("%d%d",&n,&m);
    186     for(i=0;i<=n;++i)
    187         scanf("%d",a+i);
    188     for(i=0;i<=m;++i)
    189         scanf("%d",b+i);
    190     //memcpy(a1,a,sizeof(a1));
    191     //memcpy(b1,b,sizeof(b1));
    192     //p_divmod(a,b,c,d,n,m);
    193     //memcpy(a,a1,sizeof(int)*(n+1));
    194     //memcpy(b,b1,sizeof(int)*(m+1));
    195     p_divmod(a,b,c,d,n,m);
    196     for(i=0;i<=n-m;++i)
    197         printf("%d ",c[i]);
    198     puts("");
    199     for(i=0;i<=m-1;++i)
    200         printf("%d ",d[i]);
    201     return 0;
    202 }
    View Code
  • 相关阅读:
    ConcurrentHashMap的初步使用场景、源码分析讲解(中)
    ConcurrentHashMap的初步使用场景、源码分析讲解(上)
    CyclicBarrier用例、源码分析讲解
    Semaphore用例、源码分析讲解
    CountDownLatch用例、源码分析讲解
    Condition用例、源码分析详解(下)
    Condition用例、源码分析详解(上)
    图解数据结构之数组、链表、栈、队列
    Python--day27--复习
    Python--day26--反射
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10583745.html
Copyright © 2020-2023  润新知