dp - 递推

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,,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 b1,b2,,bk

is called to be good if it is not empty and for every i (1ik) bi is divisible by i

.

Find the number of good subsequences in a

modulo 109+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 2n1

different subsequences (excluding an empty subsequence).

Input

The first line contains an integer n

(1n100000) — the length of the array a

.

The next line contains integers a1,a2,,an

(1ai106

).

Output

Print exactly one integer — the number of good subsequences taken modulo 109+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,2}, {2}

In the second example, the possible good subsequences are: {2}

, {2,2}, {2,22}, {2,14}, {2}, {2,22}, {2,14}, {1}, {1,22}, {1,14}, {22}, {22,14}, {14}

.

Note, that some subsequences are listed more than once, since they occur in the original array multiple times.

 

题意 : 给你 n 个数字,对于任意位置的数你都可以选择或者不选择,构成一个新的序列,当构成新的序列满足第一个数是1的倍数,第二个数是2的倍数..以此类推询问你方案数有多少

思路分析 :

  比赛的时候写了一个 dp,顺势推过去的,用 01 数组去优化的一个,dp[i][j] 表示到达第 i 个位置,且当前构成的序列可以整除 j 的方案数,但由于 n 很大,想的是用 01 滚动数组优化个,

结果凉掉了,就是有些状态是不会被转移过去,从而造成了丢失

  其实一维 dp 就够, dp[i] 表示当前数作为整除 i 的数的个数,倒着推就可以了

代码示例 :

#define ll long long
const ll maxn = 1e6+5;
const ll maxm = 1e5+5;
const ll mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const ll inf = 0x3f3f3f3f;

ll n;
ll a[maxm];
vector<ll>ve[maxn];

void init(){
    for(ll i = 1; i <= 1e6; i++){
        for(ll j = i; j <= 1e6; j += i){
            ve[j].push_back(i);
        }
    } 
}
ll dp[maxn];
void solve(){
    //ll pt = 1;
    //dp[0][0] = 1, dp[1][0] = 1;
    dp[0] = 1; 
    ll ans = 0;
    for(ll i = 1; i <= n; i++){
        for(ll j = ve[a[i]].size()-1; j >= 0; j--){
            ll x = ve[a[i]][j];  
            dp[x] = dp[x]+dp[x-1];
            dp[x] %= mod;
        } 
    }
    for(ll i = 1; i <= n; i++) {
        ans += dp[i];
        ans %= mod;
      //   printf("++++ i = %lld   %lld\n", i, dp[pt][i]);
    }
    cout << ans << endl;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout); 
    //init();
    cin >> n ;
    for(ll i = 1; i <= n; i++) scanf("%lld", &a[i]);
    init();
    solve();
    return 0;
}

 

posted @ 2018-11-24 07:44  楼主好菜啊  阅读(260)  评论(0编辑  收藏  举报