zoukankan      html  css  js  c++  java
  • hdu5628 Clarke and math

    题目地址

    题目链接

    题意

    [g(i)=sum_{i1|i}sum_{i_2|i_1}sum_{i_3|i_2}...sum_{i_k|i_{k-1}}f(i_k)space modspace 10^9+7 ]

    题解

    考虑当(k=1)时怎么做

    [g(i)=sum_{i_1|i}f(i_1) ]

    显然可以(O(sqrt{n}))

    我们尝试着把它表示成狄利克雷卷积的形式

    [g=f*I ]

    考虑当(k=2)时是什么样子的

    [g(i)=sum_{i_1|i}sum_{i_2|i}f(i_2) ]

    表示成狄利克雷卷积形式即为

    [g=(f*I)*I=f*I^2 ]

    同理可得当k为任意值时

    [g=f*I^k ]

    那么只需要快速幂一下就好,复杂度是(O(nlognlogk))

    注意不能枚举单个数的约数,时间复杂度会爆炸,我们可以枚举约数,并计算它对1~n中的数的贡献,这样复杂度是(O(nlogn))的,所以总的复杂度是(O(nlognlogk))

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int N = 1e5 + 10;
    const int mod = 1e9 + 7;
    
    int n, k;
    int tmp[N], I[N], g[N];
    
    void mul(int *a, int *b) {
    	for(int i = 1; i <= n; ++i) tmp[i] = 0;
    	for(int i = 1; i <= n; ++i) {
    		for(int j = 1; i * j <= n; ++j) {
    			tmp[i * j] = 1ll * (tmp[i * j] + 1ll * a[i] * b[j]) % mod;
    		}
    	}
    	for(int i = 1; i <= n; ++i) a[i] = tmp[i];
    }
    
    int main() {
    	int T; scanf("%d", &T);
    	while(T--) {
    		scanf("%d%d", &n, &k);
    		for(int i = 1; i <= n; ++i) scanf("%d", &g[i]), I[i] = 1;
    		while(k) { if(k & 1) mul(g, I); mul(I, I); k >>= 1; }
    		for(int i = 1; i < n; ++i) printf("%d ", g[i]); printf("%d
    ", g[n]);
    	}
    }
    
  • 相关阅读:
    将图片转换为base64 格式
    BFC
    面试
    不足之处
    html 调用摄像头 并抓拍
    css,js零散知识的整理
    语义化标签SEO
    Modernizr
    快速排序(2)
    快速排序(1)
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10323164.html
Copyright © 2011-2022 走看看