Codeforces Round #523 (Div. 2) C Multiplicity (DP+动态数组)

Multiplicity

time limit per test   3 seconds

memory limit per test  256 megabytes

You are given an integer array a1,a2,…,ana1,a2,…,an.

The array bb is called to be a subsequence of aa if it is possible to remove some elements from aa to get bb.

Array b1,b2,…,bkb1,b2,…,bk is called to be good if it is not empty and for every ii (1≤i≤k1≤i≤k) bibi is divisible by ii.

Find the number of good subsequences in aa 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 aa has exactly 2n−12n−1 different subsequences (excluding an empty subsequence).

Input

The first line contains an integer nn (1≤n≤1000001≤n≤100000) — the length of the array aa.

The next line contains integers a1,a2,…,ana1,a2,…,an (1≤ai≤1061≤ai≤106).

扫描二维码关注公众号,回复: 5456042 查看本文章

Output

Print exactly one integer — the number of good subsequences taken modulo 109+7109+7.

Examples

input

2
1 2

output

3

input

5
2 2 1 22 14

output

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.

题目大意:给你n个数,a1,a2...an。你可以通过删除若干个元素来构成一个新的序列,b1,b2...bk。如果对于b序列的每一个数都有bi / i 能整除,则称b序列为good。问你有多少种不同的b序列,输出结果模1e9+7;

解题思路:动态规划。如果定义一个dp[maxn][maxn]数组,dp[i][j]表示第i个数字(a[i])前可以得到的长度为j的b序列情况数。

dp方程为  dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod。但是这题n最大是1e5,二维数组开不了,所以考虑用一维数组滚动更新。

就是dp[maxn],对于每一次更新,dp[i]=(dp[i]+dp[i-1])%mod。

本题还需要定义动态数组,保存a序列里的每一个元素的因子(包括1和它本身)。用动态数组的原因是动态数组可以调节大小,不会占用不必要的内存,防止内存超限。

dp方程不是很难想,我认为这题最大的难点 是在于判断序列的当前元素是否可以放在b序列的第j个位置上。

ps:感觉直接求因子的方法很暴力,第一次看到这种方法时,感觉像是打开了新世界的大门,哈哈(原来还这样也可以)。

下面附上代码:

#define cin0  ios::sync_with_stdio(0),cin.tie(0);
#define ull unsigned long long 
#define inf 0x3f3f3f3f
#define ll long long 
#include <algorithm>
#include <iostream>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <bitset>
#include <vector>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int man=1e5+50;
const ll mod=1000000007;
vector<int>a[man];
ll dp[man*10];
int main() 
{
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>m;
		for(int j=1;j<=sqrt(m);j++){
			if(m%j==0){
				a[i].push_back(j);
				if(j*j!=m)
					a[i].push_back(m/j);
			}
		}
		sort(a[i].begin(),a[i].end());
	}
	dp[0]=1;
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=a[i].size()-1;j>=0;j--){
			dp[a[i][j]]=(dp[a[i][j]-1]+dp[a[i][j]])%mod;
			ans=(ans+dp[a[i][j]-1])%mod;//ans等到全部更新完再加也可以
		}
	}
	cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_15742375/article/details/88297765