zoukankan      html  css  js  c++  java
  • [BZOJ4913][SDOI2017]遗忘的集合

    题解:

    首先先弄出$f(x)$的生成函数
    $$f(x)=prod_{i=1}^{n} {{(frac{1}{1-x^i})}}^{a[i]}$$
    因为$f(x)$已知,我们考虑利用这个式子取推出$a[i]$
    右边的乘法显然处理起来不方便,按照套路两边取对数
    $$ln(f(x))=sum_{i=1}^{n} {-a[i]*ln(1-x^i)}$$
    然后看见$ln(1+x)$肯定是泰勒展开了,得到
    $$ln(f(x))=sum_{i=1}^{n} {-a[i]*sum_{k=1}^{INF} {frac{{(-1)}^{k-1}*{{{(-x^i)}^k}}}{k}}}$$
    化简一下就是
    $$ln(f(x))=sum_{i=1}^{n} {a[i]*sum_{k=1}^{INF} {frac{{x^{ik}}}{k}}}$$
    然后因为我们知道的$f(x)$的每一项,所以变成枚举x系数
    令$T=ik$
    $$ln(f(x))=sum_{T=1}^{INF} {x^T sum_{i|T}^{T}{frac{i*a[i]}{T}}}$$
    然后我们只需要从小到大枚举T,然后依旧算出每个$a[i]$并处理对之后的影响

    常数太大只有50。。。不知道怎么卡

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    #define ll long long
    namespace IO{
        char ss[1<<24],*A=ss,*B=ss;
        IL char gc()
        {
            return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
        }
        template<class T>void read(T &x)
        {
            rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
            while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
        }
        char sr[1<<24],z[20]; int C1=-1,Z;
        template<class T>void wer(T x)
        {
            if (x<0) sr[++C1]='-',x=-x;
            while (z[++Z]=x%10+48,x/=10);
            while (sr[++C1]=z[Z],--Z);
        }
        IL void wer1()
        {
            sr[++C1]=' ';
        }
        IL void wer2()
        {
            sr[++C1]='
    ';
        }
        template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
        template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
        template<class T>IL void MAX(T x,T y){ return x>y?x:y;} 
        template<class T>IL void MIN(T x,T y){ return x<y?x:y;}
    };
    using namespace IO;
    const int N=3e5*4;
    const double ee=1.0000000000;
    const double pi=acos(-1.0);
    struct cp{
        double a,b;
        cp operator +(const cp o) const
        {
            return (cp){o.a+a,o.b+b};
        }
        cp operator -(const cp o) const
        {
            return (cp){a-o.a,b-o.b};
        }
        cp operator *(const cp o) const
        {
            return (cp){a*o.a-b*o.b,b*o.a+a*o.b};
        }
    }a[N],b[N],w[N];
    int n,m,l,r[N],mo,mo2,mo3,x1[N],x2[N];
    int fsp(int x,int y)
    {
        ll now=1;
        while (y)
        {
            if (y&1) now=now*x%mo;
            y>>=1; x=1ll*x*x%mo;
        }
        return now;
    }
    void fft_init()
    {
        l=0; n=1; while (n<=m) n<<=1,l++;
        for (int i=0;i<n;i++) 
        {
          w[i]=(cp){cos(pi*i/n),sin(pi*i/n)};
          r[i]=(r[i/2]/2)|((i&1)<<(l-1));
        }
    }
    void fft_clear()
    {
        rep(i,0,n-1) a[i].a=a[i].b=b[i].a=b[i].b=0;
    }
    void fft(cp *a,int o)
    {
        for (int i=0;i<n;i++) if (i>r[i]) swap(a[i],a[r[i]]);
        for (int i=1;i<n;i*=2)
          for (int j=0;j<n;j+=(i*2))
          {
              cp *x1=a+j,*x2=a+i+j;
            for (int k=0;k<i;k++,x1++,x2++)
            {
                cp W=w[n/i*k]; W.b*=o;
                cp x=*x1,y=(*x2)*W;
                *x1=x+y,*x2=x-y;
            }
          }
        if (o==-1) rep(i,0,n-1) a[i].a/=n;
    }
    cp a1[N],a2[N],a3[N],b1[N],b2[N];
    void getcj(int *A,int *B,int len)
    {
        m=2*len; fft_init();
        rep(i,0,len-1)
        { 
          a1[i].a=A[i]/mo2,a2[i].a=A[i]%mo2;
          b1[i].a=B[i]/mo2,b2[i].a=B[i]%mo2;
        }
        fft(a1,1); fft(a2,1); fft(b1,1); fft(b2,1);
        rep(i,0,n-1)
        {
          a3[i]=a1[i]*b1[i];
          a1[i]=a1[i]*b2[i]+a2[i]*b1[i];
          b2[i]=a2[i]*b2[i];
        }
        fft(a3,-1); fft(a1,-1); fft(b2,-1);
        rep(i,0,len-1)
        { 
          B[i]=((ll)(a3[i].a+0.5)%mo*mo3+(ll)(a1[i].a+0.5)%mo*mo2+(ll)(b2[i].a+0.5))%mo; 
          B[i]=(B[i]+mo)%mo;
        }
        rep(i,0,n)
        {
          a1[i].a=a1[i].b=a2[i].a=a2[i].b=a3[i].a=a3[i].b=0;
          b1[i].a=b1[i].b=b2[i].a=b2[i].b=0;
        }
    }
    int C[N];
    IL void getinv(int *A,int *B,int len)
    {
        if (len==1) {B[0]=fsp(A[0],mo-2); return;}
        getinv(A,B,(len+1)>>1);
        rep(i,0,len-1) C[i]=A[i];
        getcj(B,C,len); getcj(B,C,len);
        rep(i,0,len-1) B[i]=((2ll*B[i]-C[i])%mo+mo)%mo;
    }
    IL void getdao(int *A,int *B,int len)
    {
        for (int i=0;i<len-1;i++)
          B[i]=1ll*A[i+1]*(i+1)%mo;
        B[len-1]=0; 
    }
    IL void getjf(int *A,int *B,int len)
    {
        for (int i=1;i<len;i++)
          B[i]=1ll*A[i-1]*fsp(i,mo-2)%mo;
        B[0]=0;
    }
    int C[N],D[N];
    IL void getln(int *A,int *B,int len)
    {
        getdao(A,C,len);
        getinv(A,D,len);
        getcj(C,D,len);
        getjf(D,B,len);
    }
    void getexp(int *A,int *B,int len)
    {
        if (len==1) {B[0]=1; return;}
        getexp(A,B,(len+1)>>1);
        getln(B,C,len);
        rep(i,0,len-1) C[i]=((-C[i]+A[i])%mo+mo)%mo;
        C[0]=(C[0]+1)%mo;
        getcj(C,B,len);
    }
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        int n1;
        read(n1); read(mo); mo2=3e4; mo3=mo2*mo2;
        x1[0]=1;
        rep(i,1,n1) read(x1[i]);
        getln(x1,x2,n1+1);
        rep(i,1,n1)
        {
            for (int j=2;j*i<=n1;j++)
              x2[i*j]=(x2[i*j]-1ll*x2[i]*fsp(j,mo-2))%mo;
        }
        int cnt=0;
        rep(i,1,n1) if (x2[i]) cnt++;
        wer(cnt); wer2();
        rep(i,1,n1) if (x2[i]) wer(i),wer1();
        wer2();
        fwrite(sr,1,C1+1,stdout); 
        return 0; 
    }

     #updata 12.14

    使用我优秀的常数的新模板他就过了

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    #define ll long long
    namespace IO{
        char ss[1<<24],*A=ss,*B=ss;
        IL char gc()
        {
            return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
        }
        template<class T>void read(T &x)
        {
            rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
            while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
        }
        char sr[1<<24],z[20]; int C1=-1,Z;
        template<class T>void wer(T x)
        {
            if (x<0) sr[++C1]='-',x=-x;
            while (z[++Z]=x%10+48,x/=10);
            while (sr[++C1]=z[Z],--Z);
        }
        IL void wer1()
        {
            sr[++C1]=' ';
        }
        IL void wer2()
        {
            sr[++C1]='
    ';
        }
        template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
        template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
        template<class T>IL void MAX(T x,T y){ return x>y?x:y;} 
        template<class T>IL void MIN(T x,T y){ return x<y?x:y;}
    };
    using namespace IO;
    const int N=3e5*4;
    const double ee=1.0000000000;
    const double pi=acos(-1.0);
    struct cp{
        double a,b;
        cp operator +(const cp o) const
        {
            return (cp){o.a+a,o.b+b};
        }
        cp operator -(const cp o) const
        {
            return (cp){a-o.a,b-o.b};
        }
        cp operator *(const cp o) const
        {
            return (cp){a*o.a-b*o.b,b*o.a+a*o.b};
        }
    }a[N],b[N],c[N],d[N];
    int n,m,l,r[N],mo,x1[N],x2[N];
    IL int fsp(int x,int y)
    {
        ll now=1;
        while (y)
        {
            if (y&1) now=now*x%mo;
            x=1ll*x*x%mo;
            y>>=1;
        }
        return now;
    }
    IL void clear()
    {
        for (int i=0;i<=n;i++) a[i].a=a[i].b=b[i].a=b[i].b=c[i].a=c[i].b=d[i].a=d[i].b=0;
    }
    cp *w[N],tmp[N*2];
    int p;
    IL void init()
    {
        cp *now=tmp;
        for (int i=1;i<=p;i<<=1)
        {
            w[i]=now;
            for (int j=0;j<i;j++) w[i][j]=(cp){cos(pi*j/i),sin(pi*j/i)};
            now+=i;
        }
    }
    IL void fft_init()
    {
        l=0; for (n=1;n<=m;n<<=1) l++;
        for (int i=0;i<n;i++) r[i]=(r[i/2]/2)|((i&1)<<(l-1));
    }
    void fft(cp *a,int o)
    {
        for (int i=0;i<n;i++) if (i>r[i]) swap(a[i],a[r[i]]);
        for (int i=1;i<n;i<<=1)
            for (int j=0;j<n;j+=(i*2))
            {
              cp *x1=a+j,*x2=a+i+j,*W=w[i];
              for (int k=0;k<i;k++,x1++,x2++,W++)
              {
                  cp x=*x1,y=(cp){(*W).a,(*W).b*o}*(*x2); 
                  *x1=x+y,*x2=x-y;
              }
            }
        if (o==-1) for(int i=0;i<n;i++) a[i].a/=n;
    }
    IL void getcj(int *A,int *B,int len)
    {
        rep(i,0,len)
        {
            A[i]=(A[i]+mo)%mo,B[i]=(B[i]+mo)%mo;
        }
        for (int i=0;i<len;i++)
        {
           a[i]=(cp){A[i]&32767,A[i]>>15};
           b[i]=(cp){B[i]&32767,B[i]>>15};
        }
        m=len*2; fft_init();
        fft(a,1); fft(b,1);
        for (int i=0;i<n;i++)
        {
            int j=(n-1)&(n-i);
            c[j]=(cp){0.5*(a[i].a+a[j].a),0.5*(a[i].b-a[j].b)}*b[i];
            d[j]=(cp){0.5*(a[i].b+a[j].b),0.5*(a[j].a-a[i].a)}*b[i];
        }
        fft(c,1); fft(d,1);
        double inv=ee/n;
        rep(i,0,n) c[i].a*=inv,c[i].b*=inv;
        rep(i,0,n) d[i].a*=inv,d[i].b*=inv;
        rep(i,0,len)
        {
            ll a1=c[i].a+0.5,a2=c[i].b+0.5;
            ll a3=d[i].a+0.5,a4=d[i].b+0.5;
            B[i]=(a1+((a2+a3)%mo<<15)+((a4%mo)<<30))%mo;
        }
        clear();
    }
    int C[N],D[N];
    IL void getinv(int *A,int *B,int len)
    {
        if (len==1) {B[0]=fsp(A[0],mo-2); return;}
        getinv(A,B,(len+1)>>1);
        rep(i,0,len-1) C[i]=A[i];
        getcj(B,C,len); getcj(B,C,len);
        rep(i,0,len-1) B[i]=((2ll*B[i]-C[i])%mo+mo)%mo;
    }
    IL void getdao(int *A,int *B,int len)
    {
        for (int i=0;i<len-1;i++)
          B[i]=1ll*A[i+1]*(i+1)%mo;
        B[len-1]=0; 
    }
    IL void getjf(int *A,int *B,int len)
    {
        for (int i=1;i<len;i++)
          B[i]=1ll*A[i-1]*fsp(i,mo-2)%mo;
        B[0]=0;
    }
    IL void getln(int *A,int *B,int len)
    {
        getdao(A,C,len);
        getinv(A,D,len);
        getcj(C,D,len);
        getjf(D,B,len);
    }
    void getexp(int *A,int *B,int len)
    {
        if (len==1) {B[0]=1; return;}
        getexp(A,B,(len+1)>>1);
        getln(B,C,len);
        rep(i,0,len-1) C[i]=((-C[i]+A[i])%mo+mo)%mo;
        C[0]=(C[0]+1)%mo;
        getcj(C,B,len);
    }
    int main()
    {
        freopen("10.in","r",stdin);
        freopen("1.out","w",stdout);
        int n1;
        read(n1); read(mo);
        x1[0]=1;
        rep(i,1,n1) read(x1[i]);
        p=(n1+1)<<1; init();
        getln(x1,x2,n1+1);
        rep(i,1,n1)
        {
            for (int j=2;j*i<=n1;j++)
              x2[i*j]=(x2[i*j]-1ll*x2[i]*fsp(j,mo-2))%mo;
        }
        int cnt=0;
        rep(i,1,n1) if (x2[i]) cnt++;
        wer(cnt); wer2();
        rep(i,1,n1) if (x2[i]) wer(i),wer1();
        wer2();
        fwrite(sr,1,C1+1,stdout); 
        return 0; 
    }
  • 相关阅读:
    struts2 标签 前台遍历 字符串数组 String[]
    007-服务器域名&上传网站
    006-DOS命令
    005-OSI七层模型&IP地址
    004-编程语言发展史
    003-计量单位
    002-B/S架构&C/S架构
    001-计算机的组成
    1083. List Grades (25)
    1037. Magic Coupon (25)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/10082817.html
Copyright © 2011-2022 走看看