zoukankan      html  css  js  c++  java
  • HDU-5628 Clarke and math-狄利克雷卷积+快速幂

     解法:我们观察这个g(i)的式子。我们设h(i)=1发现:

    当k=1,g=sigma(i1|i) f(i1) = sigma(i1|i) f(i1) * h(i/i1) =Dirchlet ( h* f )

    当k=2,g=sigma(i2|i1) f(i2) = Dirchlet( h * Dirchlet(h * f ) )

    ......

    当k=k,g= Dirchlet( h * Dirchlet( h * Dirchlet(h * f) ) )  里面有k个括号

    其实就是  g=h * h *h ...* f  (*代表狄利克雷卷积)

    学过狄利克雷卷积应该知道是满足结合律的,那么我们就用快速幂计算 h^k ,最后再做一次卷积就能得到结果。

    注意要储存h^k的数组g必须g[1]=1才能存下来。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e5+10;
    const int MOD=1e9+7;
    int n,k;
    LL f[N],g[N],h[N];
    
    LL c[N];
    void Dirch(LL *a,LL *b) {  //计算a=a*b的狄利克雷卷积 
        memset(c,0,sizeof(c));
        for (int i=1;i<=n;i++)
            for (int j=i;j<=n;j+=i)
                c[j]=(c[j]+a[i]*b[j/i]%MOD)%MOD;
        memcpy(a,c,sizeof(c));        
    }
    
    int main()
    {
        int T; cin>>T;
        while (T--) {
            scanf("%d%d",&n,&k);
            for (int i=1;i<=n;i++) scanf("%d",&f[i]);
            for (int i=1;i<=n;i++) h[i]=0,g[i]=1;
            h[1]=1;
            for (;k;k>>=1) {
                if (k&1) Dirch(h,g);
                Dirch(g,g);
            }
            Dirch(f,h);
            for (int i=1;i<=n;i++) printf("%lld%c",f[i],i==n ? '
    ' : ' ');
        }
        return 0;
    }
  • 相关阅读:
    多线程
    带缓存的字符输入输出流
    输入输出流(I/O)
    课本235页2-3题
    包装&工具类
    集合类SetMap
    tp框架之增删改查
    tp框架之数据添加
    tp框架之查询
    tp框架之Model类与命名空间
  • 原文地址:https://www.cnblogs.com/clno1/p/11599344.html
Copyright © 2011-2022 走看看