C. Multiplicity
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an integer array ?1,?2,…,??a1,a2,…,an.
The array ?b is called to be a subsequence of ?a if it is possible to remove some elements from ?a to get ?b.
Array ?1,?2,…,??b1,b2,…,bk is called to be good if it is not empty and for every ?i (1≤?≤?1≤i≤k) ??bi is divisible by ?i.
Find the number of good subsequences in ?a modulo 109+7109+7.
Two subsequences are considered different if index sets of numbers included in them are different. That is, the values of the elements do not matter in the comparison of subsequences. In particular, the array ?a has exactly 2?−12n−1 different subsequences (excluding an empty subsequence).
Input
The first line contains an integer ?n (1≤?≤1000001≤n≤100000) — the length of the array ?a.
The next line contains integers ?1,?2,…,??a1,a2,…,an (1≤??≤1061≤ai≤106).
Output
Print exactly one integer — the number of good subsequences taken modulo 109+7109+7.
Examples
input
Copy
2 1 2
output
Copy
3
input
Copy
5 2 2 1 22 14
output
Copy
13
Note
In the first example, all three non-empty possible subsequences are good: {1}{1}, {1,2}{1,2}, {2}{2}
In the second example, the possible good subsequences are: {2}{2}, {2,2}{2,2}, {2,22}{2,22}, {2,14}{2,14}, {2}{2}, {2,22}{2,22}, {2,14}{2,14}, {1}{1}, {1,22}{1,22}, {1,14}{1,14}, {22}{22}, {22,14}{22,14}, {14}{14}.
Note, that some subsequences are listed more than once, since they occur in the original array multiple times.
解决思路:
用dp解决,怎么想到的?不知道。这种计数的题大多都用dp,我只能这样告诉你(我是想到了,但没有想出来)。
会先想到用二维dp来解决,用dp[i][j]代表前i个数构成长度为j的b数组的方案数目,那么状态转移方程为:
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 其中j为i的约数
思路完全没问题,但是仔细想一想空间好像不够诶,然后发现求dp[i][j]的时候用到的都是dp[i - 1]的状态,考虑用滚动数组优化,这都是常规套路。。优化完之后的方程为:
dp[j] = dp[j] + dp[j - 1]
代码还是比较简单的,好好理解一下。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;
int val[maxn];
ll dp[maxn];
vector < int > facter[maxn * 10];
void Init()
{
for(int i = 1; i <= maxn * 10; ++ i)
{
for(int j = i; j <= maxn * 10; j += i)
{
facter[j].push_back(i);
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int n;
cin >> n;
Init();
for(int i = 1; i <= n; ++ i)
{
scanf("%d", &val[i]);
}
for(int i = 1; i <= n; ++ i)
{
for(int j = (int)facter[val[i]].size() - 1; j >= 0; -- j)
{
int t = facter[val[i]][j];
if(t > i) //如果t比i大是没有意义的,因为前i个数不可能构成长度为t的b数组
continue;
if(t == 1)
dp[1] = (dp[1] + 1) % mod;
else
dp[t] = (dp[t] + dp[t - 1]) % mod;
}
}
ll ans = 0;
for(int i = 1; i <= n; ++ i)
{
ans = (ans + dp[i]) % mod;
}
cout << ans << endl;
return 0;
}