hdu5628(Dirichlet convolution)

来源:互联网 发布:mac外接光驱 编辑:程序博客网 时间:2024/06/03 08:32

以前打的某一场bestcoder的题,不会,今天学习了一下狄雷克卷积(好像没有想象的辣么难,可能写的是模版题)回头写一写。

 DirichletconvolutionO(nlgn))

const int maxn = 10005;int f[maxn],g[maxn],h[maxn];for(int i = 1;i * i <= n;i++){    for(int j = i;i * j <= n;j++){        if(i == j) h[i * j] += f[i] * g[j];        else h[i * j] += f[i] * g[j] + f[j] * g[i];    }}

 f1k,使

代码如下:

////  main.cpp//  hdu5628////  Created by 黄宇凡 on 10/20/16.//  Copyright © 2016 黄宇凡. All rights reserved.//#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const LL mod = 1e9 + 7;const int maxn = 100000 + 5;LL f[maxn],g[maxn],h[maxn],tmp[maxn];int n,k;void solve(){    while(k){        if(k % 2){            for(int i = 1;i <= n;i++) tmp[i] = 0;            for(int i = 1;i * i <= n;i++){                for(int j = i;i * j <= n;j++){                    if(i == j) tmp[i * j] = (tmp[i * j] + g[i] * h[j] % mod) % mod;                    else{                        tmp[i * j] = (tmp[i * j] + g[i] * h[j] % mod + g[j] * h[i] % mod) % mod;                    }                }            }            for(int i = 1;i <= n;i++) h[i] = tmp[i];        }        for(int i = 1;i <= n;i++) tmp[i] = 0;        for(int i = 1;i * i <= n;i++){            for(int j = i;i * j <= n;j++){                if(i == j) tmp[i * j] = (tmp[i * j] + g[i] * g[j] % mod) % mod;                else{                    tmp[i * j] = (tmp[i * j] + g[i] * g[j] % mod + g[j] * g[i] % mod) % mod;                }            }        }        for(int i = 1;i <= n;i++) g[i] = tmp[i];        k >>= 1;    }    for(int i = 1;i <= n;i++) tmp[i] = 0;    for(int i = 1;i * i <= n;i++){        for(int j = i;i * j <= n;j++){            if(i == j) tmp[i * j] = (tmp[i * j] + f[i] * h[j] % mod) % mod;            else{                tmp[i * j] = (tmp[i * j] + f[i] * h[j] % mod + f[j] * h[i] % mod) % mod;            }        }    }    for(int i = 1;i <= n;i++) h[i] = tmp[i];}int main(int argc, const char * argv[]) {    int T;    cin >> T;    while(T--){        cin >> n >> k;        for(int i = 1;i <= n;i++){            scanf("%I64d",f + i);            g[i] = 1;            h[i] = 0;        }        h[1] = 1;        solve();        for(int i = 1;i <= n;i++){            printf("%I64d%c",h[i],i == n ? '\n' : ' ');        }    }    return 0;}
0 0
原创粉丝点击