CF1061C Multiplicity
题目大意
从序列中选出非空子序列,一个子序列合法需要满足。求有多少互不相等的合法子序列,答案对取模。
思路
一看到题,就会想起,然后根据这类题的套路,就是设为序列的前个数中长度为的合法子序列有多少个。不难想到转移方程:
但是这样时间复杂度就是,严重超时,所以考虑优化。
因为第一维的只和有关,而且要是的因数,所以可以预处理出所有的因数,第二维只用遍历的因数就可以了。于是我们定义为造了长度恰好为的⼦序列的⽅案数(跟序列的长度无关),为的第个因数,则转移方程如下:
这样子时间复杂度就是,就可以过了。是不是很简单?
代码
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
vector<int> ys[100001];
int n,a[100001],f[1000001],ans=0;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=sqrt(a[i]);j++){
if(a[i]%j==0){
ys[i].push_back(j);
if(j*j!=a[i]) ys[i].push_back(a[i]/j);
}
}
}
f[0]=1;
for(int i=1;i<=n;i++) {
for(int j=ys[i].size()-1;j>=0;j--){
f[ys[i][j]]=(f[ys[i][j]]+f[ys[i][j]-1])%mod;
ans=(ans+f[ys[i][j]-1])%mod;
}
}
printf("%d",ans);
return 0;
}
不要忘记点个赞哦
完结撒花
本文作者:AFewSuns
本文链接:https://www.cnblogs.com/AFewSuns/p/12760581.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步