C. Multiplicity
题目连接
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 (1≤i≤k) 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 2n−1
different subsequences (excluding an empty subsequence).
Input
The first line contains an integer n
(1≤n≤100000) — the length of the array a
The next line contains integers a1,a2,…,an
(1≤ai≤106).
Output
Print exactly one integer — the number of good subsequences taken modulo 109+7
题目大意:给你一个数组a,从中可以得到多少个子序列b,并且序列b中的bi能被i整除。首先想到的是二维数组dp[i][j],i表示在a数组的前i个数,j表示数组b的长度。那么dp[i][j]表示的就是在前i个数中数组b长度为j的个数。初始化中dp[0][0]到dp[n][0]初始化为1;
如果(a[i]%j==0)
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];否则dp[i][j]=dp[i-1][j];由于该题数据比较大,所以用二维的话不行,由于每次更新都是从上一位置得到所以可以把二维滚动成一维dp[i]中的i表示数组b的长度。每次更新只能将因数从大到小进行更新,否则会的话当前的更新会受到当前更新数的影响,自己手动进行模拟后就会发现。
#include<stdio.h>
#include<math.h>
#include<map>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
map<int,int>mp;
ll dp[1000004]= {0},ans=0;
int main()
{
int n,i,j,a;
dp[0]=1;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
vector<ll>v;
scanf("%d",&a);
for(j=1; j*j<=a; j++)
{
if(a%j==0)
{
v.push_back(j);
if(a/j!=j)
v.push_back(a/j);
}
}
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
for(int k=0;k<v.size();k++)
{
dp[v[k]]+=dp[v[k]-1];
dp[v[k]]%=mod;
}
}
for(i=1;i<=n;i++)
ans+=dp[i];
ans%=mod;
printf("%lld\n",ans);
return 0;
}
.