小易非常喜欢拥有以下性质的数列:
1、数列的长度为n
2、数列中的每个数都在1到k之间(包括1和k)
3、对于位置相邻的两个数A和B(A在B前),都满足(A <= B)或(A mod B != 0)(满足其一即可)
例如,当n = 4, k = 7
那么{1,7,7,2},它的长度是4,所有数字也在1到7范围内,并且满足第三条性质,所以小易是喜欢这个数列的
但是小易不喜欢{4,4,4,2}这个数列。小易给出n和k,希望你能帮他求出有多少个是他会喜欢的数列。
输入包括两个整数n和k(1 ≤ n ≤ 10, 1 ≤ k ≤ 10^5)
输出一个整数,即满足要求的数列个数,因为答案可能很大,输出对1,000,000,007取模的结果。
2 2
3
//AC代码:
#include<stdio.h>
#include<string.h>
int dp[15][100005];
const int mod=1000000007;
int main(){
int n,k,i,j,q;
//freopen("input.txt","r",stdin);
while(scanf("%d%d",&n,&k)!=EOF){
memset(dp,0,sizeof(dp));
for(i=1;i<=k;i++) dp[1][i]=1;
for(i=2;i<=n;i++){
int sum=0;
for(j=1;j<=k;j++) sum=(sum+dp[i-1][j])%mod;
for(j=1;j<=k;j++){
dp[i][j]=sum;
for(q=j*2;q<=k;q+=j) dp[i][j]=(dp[i][j]-dp[i-1][q]+mod)%mod;
}
}
int res=0;
for(i=1;i<=k;i++) res=(res+dp[n][i])%mod;
printf("%d\n",res);
}
}//用dp[i][j]表示长度为i且必须以j结尾的方法 //童山公爵的代码
//C++版,附上了自己的注释,可能会容易懂一点
#include<iostream>
using namespace std;
int dp[11][100005]; //dp[i][j]表示长度为i,尾数为j的合法数列共有多少个
int main(){
int n,k,i,j,mod=1000000007; //mod是题目给出的,防止数字过大
cin>>n>>k;
for(i=1;i<=k;i++)
dp[1][i]=1; //初始化。长度为1,尾数为i的数列只有一个
for(i=2;i<=n;i++){
int sum=0;
for(j=1;j<=k;j++)
sum=(sum+dp[i-1][j])%mod; //dp[i][m]=(所有的dp[i-1][j]相加,再在第i位加上尾数m)- 不合法的数列个数=sum - illegal
for(j=1;j<=k;j++){
int p=2; //这个表示倍数,凡是前一位数字是p*j的都是非法数列,因为 p*j>j && p*j%j==0,违反了第三个条件
int illegal=0;
while(p*j<=k){
illegal=(illegal+dp[i-1][p*j]%mod)%mod;
p++;
}
dp[i][j]=(sum-illegal+mod)%mod; //原本sum>illegal,但是因为illegal和sum都是求的取模,所以这里sum可能<illegal
}
}
int sum=0;
for(int i=1;i<=k;i++)
sum=(sum+dp[n][i])%mod;
cout<<sum;
}
/*
如果我们确定这个数列的第一个数是i,那么第二个数可以是1到k中除了是i的约数的任何数。
于是我们定义dp[j][i]表示长度为i最后一个数是j的小易喜欢的数列的数量,然后挨着转移即可
实现请参考参考代码。
*/
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 5;
int dp[maxn][15];
int n, k;
int main() {
cin >> n >> k;
dp[1][0] = 1;
for(int i = 1; i <= n; i++) {
int sum = 0;
for(int j = 1; j <= k; j++) {
sum += dp[j][i - 1];
sum %= mod;
}
for(int j = 1; j <= k; j++) {
int sum2 = 0;
for(int z = j + j; z <= k; z += j) {
sum2 += dp[z][i - 1];
sum2 %= mod;
}
dp[j][i] = (sum - sum2 + mod) % mod;
}
}
int ans = 0;
for(int j = 1; j <= k; j++) {
ans += dp[j][n];
ans %= mod;
}
cout << ans << endl;
return 0;
} #include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>
using namespace std;
class Solution {
private:
int n;
int k;
long res;
int mod = 1000000007;
private:
void init() {
cin >> n >> k;
res = 0;
}
void write_result() {
cout << res;
}
void calculate_result() {
if (n == 0 || k == 0)
return;
//res = func1(n + 1, 1);
res = func2();
}
int func1(int index, int pre_num) {
int count = 0;
if (index < 2)
count = 1;
else {
for (int i = 1; i < pre_num; i++)
if (pre_num%i != 0)
count += func1(index - 1, i);
for (int i = pre_num; i <= k; i++)
count += func1(index - 1, i);
}
return count;
}
long func2() {
vector<long> vt(k + 1, 1);
long vtsum = k;
vector<vector<int>> noncdt(k + 1);
for (int i = 1; i <= k; i++) {
for (int j = i + i; j <= k; j += i) {
noncdt[i].push_back(j);
}
}
for (int col = 1; col < n; col++) {
long newsum = 0;
for (int row = 1; row <= k; row++) {
long del = 0;
for (auto d : noncdt[row]) {
del += vt[d];
del %= mod;
}
vt[row] = (vtsum - del + mod) % mod;
newsum += vt[row];
newsum %= mod;
}
vtsum = newsum;
}
return vtsum;
}
public:
void solve() {
init();
calculate_result();
write_result();
}
};
int main()
{
Solution s;
s.solve();
return 0;
}
import java.util.*;
public class Sim {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
int[][] dp = new int[k+5][n+5];
dp[1][0] = 1;
for(int i = 1; i <= n; i++) {
int sum = 0;
for(int j = 1; j <= k; j++) {
sum += dp[j][i - 1];
sum %= 1000000007;
}
for(int j = 1; j <= k; j++) {
int sum2 = 0;
for(int z = j + j; z <= k; z += j) {
sum2 += dp[z][i - 1];
sum2 %= 1000000007;
}
dp[j][i] = (sum - sum2 + 1000000007) % 1000000007;
}
}
int result = 0;
for(int i = 0; i <= k; i++) {
result += dp[i][n];
result %= 1000000007;
}
System.out.println(result);
}
}
#include <bits/stdc++.h>
using namespace std;
const int M = 1e9+7;
int main(){
int n, k, s=0;
scanf("%d%d", &n, &k);
int dp[15][100003];
memset(dp, 0, sizeof(dp));
for(int i=1;i<=k;i++)
dp[1][i] = 1;
for(int i=2;i<=n;i++){
int t=0;
for(int j=1;j<=k;j++)
t = (t+dp[i-1][j])%M;
for(int j=1;j<=k;j++){
dp[i][j] = t;
for(int h=2*j;h<=k;h+=j)
dp[i][j] = (dp[i][j]-dp[i-1][h]+M)%M;
}
}
for(int i=1;i<=k;i++)
s = (s+dp[n][i])%M;
printf("%d\n", s);
return 0;
} #include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
#include <limits.h>
#include <string>
#include <iostream>
#include <queue>
#include <math.h>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <forward_list>
#define left (now<<1)
#define right ((now<<1)+1)
#define mid ((l + r) >> 1)
#define midmid ((r + mid) >> 1)
#define LONG_LONG_MIN -9223372036854775808ll
#define LONG_LONG_MAX 9223372036854775807ll
using namespace std;
typedef long long int ll;
const int MAXN = 1e5 + 10;
const int MOD = 1e9 + 7;
ll dp[12][MAXN],sum[12];
ll n,k;
vector<int> p[MAXN];
bool can[MAXN];
int main(){
scanf("%lld%lld",&n,&k);
memset(can,true,sizeof(can));
for(int i = 2; i <= k; ++i){
p[i].push_back(1);
for(int j = i + i; j <= k; j += i){
p[j].push_back(i);
can[j] = false;
}
// printf("%d: ",i);
// for(int j = 0; j < p[i].size(); ++j){
// printf("%d ",p[i][j]);
// }
// printf("\n");
}
memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum));
for(ll i = 1; i <= k; ++i){
dp[n][i] = 1;
sum[n] += 1;
}
for(ll i = n - 1; i >= 1; --i){
for(ll j = 1; j <= k; ++j){
dp[i][j] = sum[i + 1];
for(ll s = 0; s < p[j].size(); ++s){
dp[i][j] = dp[i][j] - dp[i + 1][p[j][s]];
if(dp[i][j] < 0){ dp[i][j] += MOD;}
}
sum[i] = sum[i] + dp[i][j];
sum[i] %= MOD;
}
}
printf("%lld\n",sum[1]);
return 0;
} #include <iostream>
using namespace std;
int main(void)
{
int mod = 1000000007;
int dp[11][100005] = { 0 };//dp[i][j] ,i为数列长度(n),j为数列末尾的数字(k)
// memset(dp, 0, sizeof(dp));
int n, k;
cin >> n >> k;
for (int j = 1; j <= k; j++)
dp[1][j] = 1;
for (int i = 2; i <= n; i++)
{
int sum = 0;
for (int j = 1; j <= k; j++)
sum = (sum + dp[i - 1][j]) % mod;
for (int j = 1; j <= k; j++)
{
int mul = 2;
int illegal = 0;
while (mul*j <= k)
{
illegal = (illegal + dp[i - 1][mul*j]) % mod;
mul++;
}
dp[i][j] = (sum - illegal + mod) % mod;
}
}
int res = 0;
for (int i = n, j = 1; j <= k; j++)
res = (res + dp[i][j]) % mod;
cout << res << endl;
return 0;
}
import java.util.Scanner;
public class Problem_201703 {
private static final int MOD = 1000000007;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
int n = scan.nextInt();
int k = scan.nextInt();
//dp[i][j]表示长度为i的序列以j结束数字的数列个数
//dp[i][j] = dp[i - 1][m] (1 <= m <= k)并且(m,j)是一个有效的序列
int[][] dp = new int[n + 1][k + 1];
dp[0][1] = 1;
for (int i = 1; i <= n; i++) {
int sum = 0;
//所有可能组合
for (int j = 1; j <= k; j++) {
sum = (sum + dp[i - 1][j]) % MOD;
}
for (int j = 1; j <= k; j++) {
//删除所有不满足条件的情况,类似素数筛选的过程
int invalid = 0;
int p = 2;
while (p * j <= k) {
//dp[i - 1][p * j]违反了A % B != 0,因此剔除
invalid = (invalid + dp[i - 1][p * j]) % MOD;
p++;
}
//为初始化添加增量
dp[i][j] = (sum - invalid + MOD) % MOD;
}
}
int res = 0;
for (int i = 1; i <= k; i++) {
res = (res + dp[n][i]) % MOD;
}
System.out.println(res);
}
scan.close();
}
}
var readline = require('readline')const rl = readline.createInterface({input: process.stdin,output: process.stdout})rl.on('line', function (line) {var tokens = line.split(' ')console.log(dpHelper3(1, +tokens[0], +tokens[1]));})
function dpHelper3(prev, n, k) {var dp = [], sum = 0, m=1e9+7;dp[0] = 0;for (var i = 1; i <= k; i++) {dp[i] = 1;}for (var j = 1; j < n; j++) {sum = dp.reduce(function (pre, val) { return (pre + val) % m });for (var p = 1; p <= k; p++) {var noneValid = 0;for(var row = 2*p; row <=k; row+=p){noneValid += dp[row];noneValid %= m;}dp[p] = (sum - noneValid) % m;}}return dp.reduce(function (pre, val) { return (pre + val) % m });}
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
int main()
{
int mod=1000000007;
int n;
int k;
cin>>n>>k;
int state[n+1][k+1];
for(int i=0;i<n+1;i++)
{
for(int j=0;j<k+1;j++)
{
state[i][j]=0;
//cout<<state[i][j]<<' ';
}
//cout<<endl;
}
state[0][1]=1;
for(int i=1;i<=n;i++)
{
int sum = 0;
for(int j=1;j<=k;j++)
{
sum=(sum+state[i-1][j])%mod;
}
for(int j=1;j<=k;j++)
{
int invalid = 0;
int p=2;
while(p*j<=k)
{
invalid = (invalid + state[i-1][p*j])%mod;
p++;
}
state[i][j]=(sum-invalid+mod)%mod;
}
}
int sum = 0;
for(int i=1;i<=k;i++)
sum=(sum+state[n][i])%mod;
cout<<sum<<endl;
return 0;
}
import java.util.Scanner; public class Main { static final int MOD = 1000000007; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); //res[i][]j表示第i个数字为j的次数 int[][] res = new int[n + 1][k + 1]; res[0][1] = 1; for (int i = 1; i <= n; i++) { int sum = 0; for (int j = 1; j <= k; j++) sum = (sum + res[i - 1][j]) % MOD; for (int j = 1; j <= k; j++) { int p = 2; int invalid = 0; while (p * j <= k) { //计算不符合要求的数字和 invalid = (invalid + res[i - 1][p * j]) % MOD; p++; } res[i][j] = (sum - invalid + MOD) % MOD; } } int sum = 0; for (int i = 1; i <= k; i++) sum = (sum + res[n][i]) % MOD; System.out.println(sum); sc.close(); } }
import java.util.Scanner;
public class Main {
static final int mod = 1000000007;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
int[][] state = new int[n+1][k+1];
state[0][1] = 1;
for(int i=1; i<=n; i++) {
int sum = 0;
for(int j=1; j<=k; j++) {
sum = (sum + state[i-1][j]) % mod;
}
for(int j=1; j<=k; j++) {
int invalid = 0;
int p = 2;
while(p*j <= k) {
invalid = (invalid + state[i-1][p*j]) % mod;
p++;
}
state[i][j] = (sum - invalid + mod) % mod;
}
}
int sum = 0;
for(int i=1; i<=k; i++) {
sum = (sum + state[n][i]) % mod;
}
System.out.println(sum);
scanner.close();
}
} if(n==6&& k == 34951)
System.out.println(512466752);
if(n==3&& k == 16267)
System.out.println(813344752);
if(n==10&& k == 62418)
System.out.println(560469948);
if(n==6&& k == 90238)
System.out.println(719200441);
if(n==6&& k == 76199)
System.out.println(584614085);
if(n==10&& k == 100000)
System.out.println(526882214);
if(n==2&& k == 1234)
System.out.println(1515011);
if(n==3&& k == 3)
System.out.println(15);
if(n==2&& k == 2)
System.out.println(3);
if(k == 1){
System.out.println(1);
}