[codeforces1061C]Multiplicity

探讨了在一个整数数组中寻找所有满足特定除法条件的非空子序列数量的问题,使用动态规划方法解决,并通过模运算处理大数值结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. Multiplicity
time limit per test : 3 seconds
memory limit per test : 256 megabytes

You are given an integer array a1,a2,…,ana_1,a_2,…,a_na1,a2,,an.
The array bbb is called to be a subsequence of a if it is possible to remove some elements from a to get bbb.Array b1,b2,…,bkb_1,b_2,…,b_kb1,b2,,bk is called to be good if it is not empty and for every i(1≤i≤k)bii (1≤i≤k) b_ii(1ik)bi is divisible by iii. Find the number of good subsequences in amodulo 109+710^9+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 aaa has exactly 2n−12^n−12n1 different subsequences (excluding an empty subsequence).

Input

The first line contains an integer n(1≤n≤100000)n(1≤n≤100000)n(1n100000) — the length of the array aaa.
The next line contains integers a1,a2,…,an(1≤ai≤106)a_1,a_2,…,a_n(1≤a_i≤10^6)a1,a2,,an(1ai106).
Output
Print exactly one integer — the number of good subsequences taken modulo 109+710^9+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: {111} , {1,21,21,2}, {222}.
In the second example, the possible good subsequences are: {222} , {2,22,22,2}, {2,222,222,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.

题意:
给定一个数组{aka_kak},问这个数组的所有子序列{bkb_kbk}中,有多少子序列满足:对于所有的i(1&lt;=i&lt;=k)i(1&lt;=i&lt;=k)i(1<=i<=k)满足 bib_ibiiii 的倍数,答案对109+710^9+7109+7取模

题解:
先处理出a[i]a[i]a[i]的所有因数。
接着就是DP
f[i][j]f[i][j]f[i][j]表示从111~iii前面所有序列中,长度为jjj的方案数
所以f[i][j]=(f[i][j]+f[i][j−1])f[i][j]=(f[i][j]+f[i][j-1])f[i][j]=(f[i][j]+f[i][j1])%MODMODMOD
jjj可以通过枚举a[i]a[i]a[i]的因数得到
然后我们发现可以把iii这个维度压掉…

#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
#define MOD 1000000007
using namespace std;
vector<int>v[100004];
int n,f[1000004];
int w33ha(){
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        v[i].clear();
        for(int j=1;j<=sqrt(x);j++){
            if(x%j==0){
                v[i].push_back(j);
                if(x!=j*j)v[i].push_back(x/j);
            }
        }
        sort(v[i].begin(),v[i].end());
    }
    ll ans=0;
    f[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=v[i].size()-1;j>=0;j--){
            f[v[i][j]]=(f[v[i][j]]+f[v[i][j]-1])%MOD;
            ans=(ans+f[v[i][j]-1])%MOD;
        }
    }
    printf("%d\n",ans);
    return 0;
}
int LiangJiaJun(){
    while(scanf("%d",&n)!=EOF)w33ha();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值