牛客小白月赛9: div.2 A(线性筛)

版权声明:本文为博主原创文章,你们可以随便转载 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
*/

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/84194654
今日推荐