HDU 5628 Clarke and math (积性函数模板题)

Clarke and math

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 437    Accepted Submission(s): 207


 

Problem Description

Clarke is a patient with multiple personality disorder. One day, he turned into a mathematician, did a research on interesting things.
Suddenly he found a interesting formula. Given f(i),1≤in, calculate
g(i)=∑i1∣ii2∣i1∑i3∣i2⋯∑ikik−1f(ik) mod 1000000007(1≤in)

 

Input

The first line contains an integer T(1≤T≤5), the number of test cases.
For each test case, the first line contains two integers n,k(1≤n,k≤100000).
The second line contains n integers, the ith integer denotes f(i),0≤f(i)<109+7.

 

Output

For each test case, print a line contained n integers, the ith integer represents g(i).

 

Sample Input

 

2 6 2 2 3 3 3 3 3 23 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3

 

Sample Output

 

2 7 7 15 7 23 2 9 9 24 9 39 9 50 24 39 9 102 9 39 39 90 9 102 9 102 39 39 9

Hint

In the first sample case: f(1)=2,f(2)=f(3)=f(4)=f(5)=f(6)=3 when k=1 g(1)=f(1)=2,g(2)=f(1)+f(2)=5,g(3)=f(1)+f(3)=5,g(4)=f(1)+f(2)+f(4)=2+3+3=8,g(5)=f(1)+f(5)=5,g(6)=f(1)+f(2)+f(3)+f(6)=2+3+3+3=10 when k=2 g(1)=f(1)=2,g(2)=f(1)+(f(1)+f(2))=7,g(3)=f(1)+(f(1)+f(3))=7,g(4)=f(1)+(f(1)+f(2))+(f(1)+f(4))=15,g(5)=f(1)+(f(1)+f(5))=7,g(6)=f(1)+(f(1)+f(2))+(f(1)+f(3))+(f(1)+f(2)+f(3)+f(6))=23 Therefore output 2 7 7 15 7 23

 

Source

BestCoder Round #72 (div.2)

 

Recommend

hujie   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 

#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;

#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)

#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long

const int  maxn =3e5+5;
const int mod=1e9+7;
/*
题目大意:按形式求卷积,给定f函数的映射关系。

可以看出这个运算可以简化数学表达:一系列狄利克雷卷积运算相乘,
因为交换律和结合律,可以看成卷积的幂次,于是乎就可以快速幂优化。

卷积的模板题。

*/

ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }

ll F[maxn],H[maxn],G[maxn],tmp[maxn];///过渡数组tmp
int n,k;

void calc(ll * h,ll* g)///两个函数的卷积运算,sum d|n h(d)*g(n/d)。
{
    memset(tmp,0,sizeof(tmp));
    for(int i=1;i*i<=n;i++)
    {
        tmp[i*i]+=h[i]*g[i]%mod;
        if(tmp[i*i]>=mod) tmp[i*i]-=mod;

        for(int j=i+1;i*j<=n;j++)
        {
            tmp[i*j]+=h[i]*g[j]%mod+h[j]*g[i]%mod;
            while(tmp[i*j]>=mod) tmp[i*j]-=mod;
        }
    }
    memcpy(h,tmp,sizeof(tmp));
}

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%lld",&F[i]) , G[i]=1,H[i]=0;
        H[1]=1;///答案函数
        while(k)
        {
            if(k&1) calc(H,G);
            calc(G,G);
            k>>=1;
        }
        calc(F,H);
        for(int i=1;i<=n;i++) printf("%lld%c",F[i],i==n?'\n':' ');
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/82387425
今日推荐