luoguP4705 게임 다항식 연산 + NTT

3987 단어
매우 재미있는 다항식 추식 서브문제를 많이 쌓아라. 
code:
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define ull unsigned long long 
using namespace std;
namespace IO
{
    char buf[100000],*p1,*p2;
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
    int rd()
    {
        int x=0; char s=nc();
        while(s='0') x=(((x<<2)+x)<<1)+s-'0',s=nc();
        return x;
    }     
    void print(int x) {if(x>=10) print(x/10);putchar(x%10+'0');}
    void setIO(string s)
    {
        string in=s+".in";
        string out=s+".out";
        freopen(in.c_str(),"r",stdin);
        // freopen(out.c_str(),"w",stdout);
    } 
};  
const int G=3;
const int N=4000005;
const int mod=998244353;               
int A[N],B[N],w[2][N],mem[N*100],*ptr=mem,tmpa[N],tmpb[N],aa[N],bb[N];      
inline int qpow(int x,int y)
{
    int tmp=1; 
    for(;y;y>>=1,x=(ll)x*x%mod)     if(y&1) tmp=(ll)tmp*x%mod;
    return tmp;
}  
inline int INV(int a) { return qpow(a,mod-2); }    
inline void ntt_init(int len)
{
    int i,j,k,mid,x,y;  
    w[1][0]=w[0][0]=1,x=qpow(3,(mod-1)/len),y=qpow(x,mod-2);
    for (i=1;ik)    swap(a[i],a[k]);
        for(j=len>>1;(k^=j)>=1);
    }
    for(mid=1;mid>1,la);
    int l=len<<1,i;
    memset(A,0,l*sizeof(A[0]));          
    memset(B,0,l*sizeof(A[0]));
    memcpy(A,a,min(la,len)*sizeof(a[0]));                                                  
    memcpy(B,b,len*sizeof(b[0]));         
    ntt_init(l);
    NTT(A,l,1),NTT(B,l,1);  
    for(i=0;i>1,la);            
    for(i=0;i>1);++i) aa[i]=b[i];         
    get_ln(b,bb,len,len>>1);                                            
    for(i=0;ila?0:a[i]))%mod;                            
    bb[0]=(bb[0]+1)%mod;
    ntt_init(l);
    NTT(aa,l,1),NTT(bb,l,1);
    for(i=0;i=b.len)   c.a[i]=a[i];
            else c.a[i]=(a[i]-b.a[i]+mod)%mod;
        }
        return c;
    }
    poly operator/(poly u)
    {
        int n=len,m=u.len,l=1;
        while(l>1;   
    return solve(l,mid,ar)*solve(mid+1,r,ar);  
}
#define MAX 100007 
int n,m;
int bo[N],al[N],fac[N],inv[N];      
int main() 
{ 
    int i,j; 
    // IO::setIO("input"); 
    scanf("%d%d",&n,&m);   
    for(i=1;i<=n;++i)   scanf("%d",&al[i]);   
    for(i=1;i<=m;++i)   scanf("%d",&bo[i]);           
    inv[0]=fac[0]=1;   
    for(i=1;i<=MAX;++i) fac[i]=(ll)fac[i-1]*i%mod,inv[i]=INV(fac[i]);          
    poly _A=solve(1,n,al);     
    poly _B=solve(1,m,bo);        
    _A=_A.dao()*_A.Inv(MAX);          

    _B=_B.dao()*_B.Inv(MAX);                  


    poly tmp(2);   
    tmp.a[0]=0,tmp.a[1]=1;      

    _A=_A*tmp; 
    _B=_B*tmp;
    for(i=0;i

좋은 웹페이지 즐겨찾기