Codeforces Round #523 (Div. 2)C. Multiplicity
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;
}
.