HDU.5628.Clarke and math(狄利克雷卷积 快速幂)
\(Description\)
$$g(i)=\sum_{i_1|i}\sum_{i_2|i_1}\sum_{i_3|i_2}\cdots\sum_{i_k|i_{k-1}}f(i_k)\ mod\ 1000000007$$
给出\(n,k,f[1\sim n]\),求\(g[1\sim n]\).
\(Solution\)
首先狄利克雷卷积(Dirichlet Product):设\(f(n),g(n)\)是两个数论函数,它们的Dirichlet乘积也是一个数论函数,
\]
简记为\(h(n)=f(n)*g(n)\)。
狄利克雷卷积有几个性质:
1. 满足交换律 \(f*g=g*f\)
2. 满足结合律 \((f*g)*h=f*(g*h)\)
3. 满足分配率 \(f*(g+h)=f*g+f*h\)
4. 存在单位元\(e\),使得\(e*f=f*e=f\)
回到本题。设\(I(x)=1\).
将式子依次展开
$$f'(i_{k-1})=\sum_{i_k|i_{k-1}}f(i_k)=\sum_{i_k|i_{k-1}}f(i_k)I(\frac{i_{k-1}}{i_k})\ ,\ \ 即f'=fI$$
$$f''(i_{k-2})=\sum_{i_{k-1}|i_{k-2}}f'(i_k-1)=\sum_{i_{k-1}|i_{k-2}}f'(i_k-1)I(\frac{i_{k-2}}{i_{k-1}})\ ,\ \ 即f''=f'*I$$.
\(\ldots\)
这样下去可以得到\(g=I*I*I*\cdots*I*f(k个I)\)。由于狄利克雷卷积满足结合律,所以\(k个I\)的狄利克雷卷积可以用快速幂\(logk\)计算。
计算狄利克雷卷积时,如果对每个\(g(i),1\leq i\leq n\)都按照定义枚举其约数计算,时间肯定爆炸。所以可以枚举约数,再枚举这些约数可以对哪些值给出贡献,那么计算一次狄利克雷卷积的复杂度就是\(O(nlogn)\),总复杂度\(O(nlognlogk)\)。
/*
刚开始要将ans初始化为单位元,即ans[2~n]=0,ans[1]=1,这样最初乘一个函数还是这个函数本身,即1
初始化x为I,I(n)=1
注:1.两个函数狄利克雷卷积是个函数
2.加两个数取模不能直接用-=mod
*/
#include<cstdio>
#include<cctype>
#include<cstring>
#define gc() getchar()
typedef long long LL;
const int N=1e5+5,mod=1e9+7;
int n,k;
LL f[N],ans[N],tmp[N],x[N];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
#define Mod(x) x>=mod?x-=mod:0
void Dirichlet(LL *a,LL *b)//a*b
{
memset(tmp,0,sizeof tmp);
for(int i=1;i*i<=n;++i)
{
tmp[i*i]+=a[i]*b[i]%mod, Mod(tmp[i*i]);
for(int j=i+1;i*j<=n;++j)//下边加上a[i]*b[j]和a[j]*b[i],所以j从i+1开始即可
(tmp[i*j]+=a[i]*b[j]%mod+a[j]*b[i]%mod)%=mod;//注意这加两个数不能一步用Mod取模。。
}
memcpy(a,tmp,sizeof tmp);
}
void Solve()
{
for(int i=1;i<=n;++i) x[i]=1,ans[i]=0;//x:I^0
ans[1]=1;//ans:e
for(;k;k>>=1,Dirichlet(x,x))
if(k&1) Dirichlet(ans,x);
Dirichlet(ans,f);
for(int i=1;i<=n;++i) printf("%lld%c",ans[i],i==n?'\n':' ');//空格及换行符有要求
}
int main()
{
for(int t=read();t--;)
{
n=read(),k=read();
for(int i=1;i<=n;++i) f[i]=read();
Solve();
}
return 0;
}
HDU.5628.Clarke and math(狄利克雷卷积 快速幂)的更多相关文章
- HDU 5628 Clarke and math Dirichlet卷积+快速幂
题意:bc round 72 中文题面 分析(官方题解): 如果学过Dirichlet卷积的话知道这玩意就是g(n)=(f*1^k)(n), 由于有结合律,所以我们快速幂一下1^k就行了. 当然,强行 ...
- HDU 5628 Clarke and math——卷积,dp,组合
HDU 5628 Clarke and math 本文属于一个总结了一堆做法的玩意...... 题目 简单的一个式子:给定$n,k,f(i)$,求 然后数据范围不重要,重要的是如何优化这个做法. 这个 ...
- HDU 5628 Clarke and math dp+数学
Clarke and math 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5628 Description Clarke is a patient ...
- HDU 1757 A Simple Math Problem (矩阵快速幂)
题目 A Simple Math Problem 解析 矩阵快速幂模板题 构造矩阵 \[\begin{bmatrix}a_0&a_1&a_2&a_3&a_4&a ...
- hdu 1757 A Simple Math Problem_矩阵快速幂
题意:略 简单的矩阵快速幂就行了 #include <iostream> #include <cstdio> #include <cstring> using na ...
- hdu 5187 zhx's contest [ 找规律 + 快速幂 + 快速乘法 || Java ]
传送门 zhx's contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- HDU 2855 斐波那契+矩阵快速幂
http://acm.hdu.edu.cn/showproblem.php?pid=2855 化简这个公式,多写出几组就会发现规律 d[n]=F[2*n] 后面的任务就是矩阵快速幂拍一个斐波那契模板出 ...
- HDU 5950:Recursive sequence(矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:给出 a,b,n,递推出 f(n) = f(n-1) + f(n-2) * 2 + n ^ 4. f ...
- HDU1757 A Simple Math Problem 矩阵快速幂
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
随机推荐
- 【黑客免杀攻防】读书笔记8 - 软件逆向工程基础2(if-else,三目运算符)
0x1 if-else分支 if-else分支4种状态 1.1 以常量为判断条件的简单if-else分支 C源代码: 单层if-else判断,常量为判断条件 int _tmain(int argc, ...
- linux 串口0x03,0x13的问题【转】
linux 串口0x03,0x13的问题 本人最近在调linux串口的时候,发现其他数据接收正常,但是0x13怎么也接收不到,后面发现了这篇文章,两天的bug终于解决了,原来是linux底层uart配 ...
- mysql caching_sha2_password异常分析
使用navicat连接mysql报错 解决办法: 通过命令行登录mysql后,输入: alter user 'root'@'localhost' IDENTIFIED WITH mysql_nativ ...
- mysql主从配置 转自http://www.cnblogs.com/sustudy/p/4174189.html
1.确保主数据库与从数据库一模一样. 例如:主数据库里的a的数据库里有b,c,d表,那从数据库里的就应该有一个模子刻出来的a的数据库和b,c,d表 2.在主数据库上创建同步账号. GRANT REPL ...
- servlet请求中的信息
在servlet中HttpServeltRequest中有一个方法getRequestURL() 假如我们平常输入的地址是:localhost/Demo1/TestServlet?hello=worl ...
- Protocol Buffers简明教程
随着微服务架构的流行,RPC框架渐渐地成为服务框架的一个重要部分. 在很多RPC的设计中,都采用了高性能的编解码技术,Protocol Buffers就属于其中的佼佼者. Protocol Buffe ...
- Java 清理和垃圾回收
java.lang.ref.cleaner包 finalize()//该方法已过时,有风险,慎用 1.对象不可能被垃圾回收 2.垃圾回收并不等于"析构" 只有当垃圾回收发生时fin ...
- php中0,空,null和false之间区别
$a = 0; $b="0"; $c= ''; $d= null; $e = false; echo "5个变量-原始测试类型"; var_dump($a);/ ...
- poj2279 线性dp
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using n ...
- linux下如何使用gdb调试
gdb是linux下非常好用的一个调试工具,虽然它是命令行模式的调试工具,但是它的功能强大到你无法想象,这里简单介绍下gdb下常用的命令. 首先编译生成可执行文件(这里的test.c是一个简单的求前n ...