版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/84194654
链接:https://ac.nowcoder.com/acm/contest/275/J
来源:牛客网
题目描述
定义 f(n,k) 表示将 n 拆分成 k 个有序正整数乘积的方案数。
给定 n,k,,求f(1,k)~f(n,k)
举个例子,假设要求 f(4,3) ,因为
所以 f(4,3)=6 。
输入描述:
第一行两个正整数 n,k 。
输出描述:
设,且gi ≥ 0,且gi尽可能的小 设 你只需要输出T就行了
输入
4 3
输出
11
说明
f1,3=1,f2,3=3,f3,3=3,f4,3=6
有点懒,直接放下官网题解吧
那么一个线性筛就搞定了
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
LL F[10000005], inv[686] = {0,1};
int cnt, flag[10000005], num[10000005], pri[1000005];
int main(void)
{
LL ans, n, i, j, k;
scanf("%lld%lld", &n, &k);
k %= mod;
for(i=2;i<=666;i++)
inv[i] = (mod-mod/i)*inv[mod%i]%mod;
for(i=2;i<=10000000;i++)
{
if(flag[i]==0)
{
num[i] = 1;
pri[++cnt] = i;
F[i] = k;
}
for(j=1;j<=cnt&&i*pri[j]<=10000000;j++)
{
flag[i*pri[j]] = 1;
if(i%pri[j]==0)
{
num[i*pri[j]] = num[i]+1;
F[i*pri[j]] = F[i]*(num[i]+k)%mod*inv[num[i]+1]%mod;
break;
}
else
{
num[i*pri[j]] = 1;
F[i*pri[j]] = F[i]*k%mod;
}
}
}
ans = 0;
F[1] = 1;
for(i=1;i<=n;i++)
ans ^= (F[i]+i)%mod;
printf("%lld\n", ans);
return 0;
}
/*
10000000 1000000000000000000
*/