【BZOJ3157/3516】国王奇遇记(数论)
【BZOJ3157/3516】国王奇遇记(数论)
题面
题解
先考虑怎么做\(m\le 100\)的情况、
令\(f(n,k)=\displaystyle \sum_{i=1}^n i^k m^i\),然后推式子:
f(n+1,k)&=\sum_{i=1}^{n+1} i^km^i=m+\sum_{i=2}^{n+1}i^km^i\\
&=m+\sum_{i=1}^n (i+1)^km^{i+1}\\
&=m+m\sum_{i=1}^n m^i\sum_{j=0}^k{k\choose j}i^j\\
&=m+m\sum_{j=0}^{k}{k\choose j}\sum_{i=1}^n i^jm^i\\
&=m+m\sum_{j=0}^k {k\choose j}f(n,j)
\end{aligned}\]
这样子可以做到\(O(nm)\)。
考虑继续处理这个式子:
f(2n,k)&=\sum_{i=1}^{2n}i^km^i=f(n,k)+m^n\sum_{i=1}^n (i+n)^km^i\\
&=f(n,k)+m^n\sum_{i=1}^n m^i\sum_{j=0}^k {k\choose j}i^jn^{k-j}\\
&=f(n,k)+m^n\sum_{j=0}^k{k\choose j}n^{k-j}\sum_{i=1}^ni^j m^i\\
&=f(n,k)+m^n\sum_{j=0}^k{k\choose j}n^{k-j}f(n,j)
\end{aligned}\]
既然这样子就可以愉快的倍增了。
时间复杂度\(O(m^2\log n)\)
#include<iostream>
using namespace std;
#define MOD 1000000007
int n,m,f[222],C[222][222],pw[222],tmp[222];
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
void Solve(int n)
{
if(n==1){for(int i=0;i<=m;++i)f[i]=m;return;}
Solve(n>>1);int pwm=fpow(m,n>>1);
pw[0]=1;for(int i=1;i<=m;++i)pw[i]=1ll*pw[i-1]*(n>>1)%MOD;
for(int i=0;i<=m;++i)tmp[i]=f[i];
for(int k=0;k<=m;++k)
for(int j=0;j<=k;++j)
tmp[k]=(tmp[k]+1ll*pwm*C[k][j]%MOD*pw[k-j]%MOD*f[j])%MOD;
for(int i=0;i<=m;++i)f[i]=tmp[i];
if(n&1)
{
for(int i=0;i<=m;++i)tmp[i]=m;
for(int k=0;k<=m;++k)
for(int j=0;j<=k;++j)
tmp[k]=(tmp[k]+1ll*m*C[k][j]%MOD*f[j])%MOD;
for(int i=0;i<=m;++i)f[i]=tmp[i];
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<=m;++i)C[i][0]=1;
for(int i=1;i<=m;++i)
for(int j=1;j<=i;++j)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
Solve(n);
cout<<f[m]<<endl;
return 0;
}
然而如果你直接把上面的代码去交加强版就会\(T\)飞(时限\(1s\))
考虑更加优秀的方法。
直接令\(f(k)=\sum_{i=1}^n i^k m^i\)。
然后拿出来强行做个差:
mf(k)-f(k)&=\sum_{i=1}^n i^k m^{i+1}-\sum_{i=1}^n i^km^i\\
&=n^km^{n+1}+\sum_{i=1}^{n} (i-1)^km^i-\sum_{i=1}^n i^k m^i\\
&=n^km^{n+1}+\sum_{i=1}^{n}m^i((i-1)^k-i^k)\\
&=n^km^{n+1}+\sum_{i=1}^n m^i \sum_{j=0}^{k-1}{k\choose j}(-1)^{k-j}i^j\\
&=n^km^{n+1}+\sum_{j=0}^{k-1}{k\choose j}(-1)^{k-j}\sum_{i=1}^n i^jm^i\\
&=n^km^{n+1}+\sum_{j=0}^{k-1}{k\choose j}(-1)^{k-j}f(j)\\
\end{aligned}\]
于是就可以做到\(O(m^2)\)了。
注意\(m=1\)的时候需要特判。
#include<iostream>
using namespace std;
#define MOD 1000000007
int n,m,f[1010],C[1010][1010],pw[1010],tmp[1010];
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int main()
{
cin>>n>>m;
if(m==1){cout<<1ll*n*(n+1)/2%MOD<<endl;return 0;}
int inv=fpow(m-1,MOD-2);
for(int i=0;i<=m;++i)C[i][0]=1;
for(int i=1;i<=m;++i)
for(int j=1;j<=i;++j)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
f[0]=1ll*(fpow(m,n)+MOD-1)*inv%MOD*m%MOD;
for(int k=1,pwm=fpow(m,n+1),pw=n;k<=m;++k,pw=1ll*pw*n%MOD)
{
f[k]=1ll*pw*pwm%MOD;
for(int j=0,d=((k&1)?(MOD-1):1);j<k;++j,d=MOD-d)
f[k]=(f[k]+1ll*C[k][j]*d%MOD*f[j])%MOD;
f[k]=1ll*f[k]*inv%MOD;
}
cout<<f[m]<<endl;
return 0;
}
似乎还要一个更强的版本,然而我不会做QwQ。
【BZOJ3157/3516】国王奇遇记(数论)的更多相关文章
- bzoj3157 3516 国王奇遇记
Description Input 共一行包括两个正整数N和M. Output 共一行为所求表达式的值对10^9+7取模的值. 特判m=1 m≠1时: 设S[u]=sigma(i^u*m^i) m*S ...
- BZOJ3157: 国王奇遇记 & 3516: 国王奇遇记加强版
令\[S_i=\sum_{k=1}^n k^i m^k\]我们有\[\begin{eqnarray*}(m-1)S_i & = & mS_i - S_i \\& = & ...
- bzoj 3157 && bzoj 3516 国王奇遇记——推式子
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3157 https://www.lydsy.com/JudgeOnline/problem.p ...
- bzoj 3157 & bzoj 3516 国王奇遇记 —— 推式子
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3157 https://www.lydsy.com/JudgeOnline/problem.p ...
- BZOJ3157/BZOJ3516 国王奇遇记(矩阵快速幂/数学)
由二项式定理,(m+1)k=ΣC(k,i)*mi.由此可以构造矩阵转移,将mi*ik全部塞进去即可,系数即为组合数*m.复杂度O(m3logn),因为大常数喜闻乐见的T掉了. #include< ...
- 3157: 国王奇遇记 & 3516: 国王奇遇记加强版 - BZOJ
果然我数学不行啊,题解君: http://www.cnblogs.com/zhuohan123/p/3726933.html const h=; var fac,facinv,powm,s:..]of ...
- 【BZOJ4126】【BZOJ3516】【BZOJ3157】国王奇遇记 线性插值
题目描述 三倍经验题. 给你\(n,m\),求 \[ \sum_{i=1}^ni^mm^i \] \(n\leq {10}^9,1\leq m\leq 500000\) 题解 当\(m=1\)时\(a ...
- BZOJ 3516 国王奇遇记加强版(乱推)
题意 求\(\sum_{k=1}^{n}k^mm^k (n\leq1e9,m\leq1e3)\) 思路 在<>中有一个方法用来求和,称为摄动法. 我们考虑用摄动法来求这个和式,看能不能得到 ...
- 【BZOJ】【3157】&【BZOJ】【3516】国王奇遇记
数论 题解:http://www.cnblogs.com/zhuohan123/p/3726933.html copy一下推导过程: 令$$S_i=\sum_{k=1}^{n}k^im^k$$ 我们有 ...
随机推荐
- 堆排、python实现堆排
一.堆-完全二叉树 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),是不稳定排序 堆排序中的堆有大顶堆.小顶堆两种.他们都是完 ...
- 【学习总结】GirlsInAI ML-diary day-2-Python版本选取与Anaconda中环境配置与下载
[学习总结]GirlsInAI ML-diary 总 原博github链接-day2 Python版本选取与Anaconda中环境配置与下载 1-查看当前Jupyter的Python版本 开始菜单选J ...
- C# 和 c++的语法不同点
GC Garbage Collection 垃圾回收器 自动释放资源 关键字: new 1.创建对象 2.隐藏从父类继承的同名函数 using 1.引用命名空间 2. using(FileStrea ...
- 【Python3练习题 019】 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
后一个分数的分子=前一个分数的分子+分母,后一个分数的分母=前一个分数的分子,循环个20次就有结果.注意,假设分子为a,分母为b,虽然 a = a + b, 但此时a已经变成 a+b 了,所以再给b重 ...
- lumen 5.6 设置APP_KEY为32位长的随机字符串
在 App\Console\Commands下 添加以下内容的KeyGenerateCommand.php文件 <?php namespace App\Console\Commands; use ...
- CLOUD常用表
采购采购订单(t_PUR_POOrder, t_PUR_POOrderEntry)-收料通知单(T_PUR_Receive,T_PUR_ReceiveEntry)-采购入库单(T_STK_INSTOC ...
- 关于golang.org/x包问题
关于golang.org/x包问题 由于谷歌被墙,跟谷歌相关的模块无法通过go get来下载,解决方法: git clone https://github.com/golang/net.git $GO ...
- 如何使用apache自带的ab压力测试工具
ab是apache自带的一个很好用的压力测试工具,当安装完apache的时候,就可以在bin下面找到ab 1 我们可以模拟100个并发用户,对一个页面发送1000个请求 ./ab -n1000 -c1 ...
- python学习笔记(10)--组合数据类型(集合类型)
集合类型 集合是多个元素的无序组合,每个元素唯一,不存在相同类型,每个元素是不可变类型.用{}表示,元素间用逗号分隔.建立结合类型用{},或set函数,如果是空集合必须用set. >>&g ...
- kubernetes资源类别介绍
类别 名称 资源对象 Pod.ReplicaSet.ReplicationController.Deployment.StatefulSet.DaemonSet.Job.CronJob.Horizon ...