题目链接
题意:
给定一个数组{},问这个数组的所有子序列{}中,有多少子序列满足:对于所有的满足 是 的倍数,答案对取模
题解:
先处理出的所有因数。
接着就是DP
长度为j的方案数
所以
j可以通过枚举的因数得到
别忘了 dp[j]%=mod
其中 在枚举所有因数的时候用到一个很巧妙的方法
用vector存储 (n*logn)的复杂度
vector<int> pr[1000005];
for(int i=1000000;i>=1;--i)
for(int j=i;j<=1000000;j+=i)
pr[j].push_back(i);
为什么要倒着存因子(从大到小存),因为它会重复加(我们只是用到了他最大的因子,其他的因子我们通过dp[i-1]获得)、
即 1 2 这两个数
1的因子只有1
2的因子有1 和 2
从小到大 dp[1]=0+dp[0]=0+1=1 ; dp[1]=dp[1]+dp[0]=1+1=2; dp[2]=0+dp[1]=2;
从大到小 dp[1]=0+d[0]=0+1=1; dp[2]=d[2]+d[1]=0+1=1; dp[1]=d[1]+dp[0]=1+1=2;
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
vector<int> pr[1000005];
int dp[1000005], ans=0, n, x;
int main() {
for(int i=1000000;i>=1;--i)
for(int j=i;j<=1000000;j+=i)
pr[j].push_back(i);
dp[0]=1;
cin>>n;
for(int i=1;i<=n;++i) {
cin>>x;
for(auto x : pr[x]) dp[x]=(dp[x]+dp[x-1])%mod;
}
for(int i=1;i<=n;++i) ans=(ans+dp[i])%mod;
cout<<ans<<endl;
return 0;
}
改成一维的vector
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll ;
const int MAX=1e6+10;
ll n,ans;
ll a[MAX];
ll dp[MAX];
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
dp[0]=1;
for(int i=1;i<=n;i++)
{
vector<ll>v;
for(int j=1;j*j<=a[i];j++)
{
if(a[i]%j==0)
{
v.push_back(j);
if(j*j!=a[i])
v.push_back(a[i]/j);
}
}
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
for(auto &it: v)
{
dp[it]+=dp[it-1];
dp[it]%=mod;
}
}
for(int i=1;i<=n;i++)
ans+=dp[i];
ans%=mod;
printf("%lld\n",ans);
return 0;
}