• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
CodeForces-1061C (计数类背包)

题目

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 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).

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[i][j]\)表示考虑前i个物品,当背包容量为j时的方案数为多少

显然

\(\begin{equation} dp[i][j]=\left\{ \begin{aligned} dp[i - 1][j],\quad a[i] != a[j]\\ dp[i - 1][j - 1] + dp[i - 1][j],\quad a[i] \bmod j = 0\\ \end{aligned} \right . \end{equation}\)

当然\(dp[i][j]\)可以换成一维的滚动数组,然后从倒序更新

暴力的话,\(O(n^2)\)很容易超时,观察上述等式,当且仅当\(j \mid a_i\)时,\(dp[j]\)(滚动数组)才会被更新,否则其和上一层相等,所以我们每次只更新因子,其余的不用更新,所以遍历\(1到\sqrt{n}\),把因子放进去,然后每次只遍历因子

复杂度\(O(n\sqrt{n})\)

Code

/* CodeForces-1061C */
#include <iostream>
#include <numeric>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 1e6 + 10, mod = 1e9 + 7;

// 计数类背包
// dp[i][j] 表示从前i个数 抽取大小为j的数的个数
// | dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] if (j | a[i])整除
// | dp[i][j] = dp[i - 1][j]
// dp[1][0] = 1

// 滚动数组
// dp[j] = dp[j] + dp[j - 1];

int a[N];
long long dp[N];

long long add(long long a, long long b) {
	return (a % mod + b % mod) % mod;
}

int main() {
	int n; cin >> n;

	dp[0] = 1;

	for(int i = 1; i <= n; i ++) {
		cin >> a[i];

		vector<int> curr;
		for (int j = 1; j <= a[i] / j; j ++) {
			if (a[i] % j == 0) {
				curr.push_back(j);
				if (a[i] / j != j)
					curr.push_back(a[i] / j);
			}	
		}
		sort(curr.begin(), curr.end(), greater<int>());
		for (auto &x: curr) {
			dp[x] = add(dp[x], dp[x - 1]);
		}
	}
	long long ans = 0;
	for (int i = 1; i <= n; i ++) ans = add(ans, dp[i]);
	cout << ans;
}
posted on 2023-01-13 11:26  Jack404  阅读(62)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3