P4167 [Violet]樱花

题目背景

又到了一年樱花盛开的时节。Vani 和妹子一起去看樱花的时候,找到了一棵大大的樱 花树,上面开满了粉红色的樱花。Vani 粗略估计了一下,一共有足足  n! 片花瓣。

Vani 轻柔地对她说:“你知道吗?这里面的一片花瓣代表着你,我从里面随机摘一片,能和你相遇的概率只有1/n!那么小。我该是多么的幸运,才让你今天这么近地站在我面前。

相信我,我一定会把这亿万分之一的缘分变为永远。”

粉红的樱花漫天飞舞,妹子瞬间被 Vani 感动了。她轻轻地牵起了他的手,和他相依而 坐。这时,她突然看到田野的尽头也长着两棵樱花树,于是慢慢地把头靠在 Vani 的肩上,在他耳边低语:“看到夕阳里的那两棵樱花树了吗?其中一棵树上的一片花瓣是你,另一棵树上的一片花瓣是我,如果有人从这棵摘下一片,从那棵采下一瓣,我们相遇的概率会不会正好是1/n!呢?”

Vani 的大脑飞速运作了一下,立即算出了答案。正要告诉妹子,她突然又轻轻地说:“以 前你总是说我数学不好,但是这种简单的题我还是会算的。你看假如左边那棵树上有 x片花

瓣,右边那个有 y 片花瓣,那么我们相遇的概率不就是1/x+1/y么,不过有多少种情况能使

它正好可以等于1/n!呢?这个你就帮我算一下吧~”

显然,面对天然呆的可爱妹子,Vani 不但不能吐槽她的渣数学,而且还要老老实实地 帮她算出答案哦。

题目描述

求不定方程

?1/x+1/y=1/n!

的正整数解(x,y)的数目。

输入格式

一个整数n。

输出格式

一个整数,表示有多少对 (x,y) 满足题意。答案对10^9+7取模。

输入输出样例

输入 #1

2

输出 #1

3

说明/提示

样例说明

共有三个数对(x,y)满足条件,分别是 (3,6)(4,4)和(6,3)。

数据范围与约定 对于 30% 的数据,保证n≤100。

思路

共有三个数对(x,y)满足条件,分别是 (3,6)(4,4)和(6,3)。

对(n!)^2唯一分解的时候,最暴力的做法是直接分解,也就是对每一个n,枚举每个小于sqrt(n)的质数,时间复杂度为O(sqrt(n)*)

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=1000010;
const int Mod=1e9+7;

int n,ans;
long long fj[N],v[N];
long long p[N],tot=0;

void work(int n) {
	memset(p,0,sizeof(p));
	memset(v,0,sizeof(v));
	tot=0;
	for(int i=2; i<=n; i++) {
		if(!v[i]) {
			v[i]=i;
			tot++;
			p[tot]=i;
		}
		for(int j=1; j<=tot; j++) {
			if(i*p[j]>n||v[i]<p[j])
				break;
			v[p[j]*i]=p[j];
		}
	}
}

int main () {
	scanf("%d",&n);
	work(n);
	for(int i=1; i<=n; i++)
		for(int j=i; j!=1; j/=v[j]) {
			++fj[v[j]];
			fj[v[j]]%=Mod;
		}
	ans=1;
	for(int i=1; i<=n; i++)
		ans=(ans*(fj[i]<<1|1))%Mod;
	printf("%lld\n",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/mysh/p/11297314.html

时间: 2024-08-30 12:29:25

P4167 [Violet]樱花的相关文章

数论——[Violet]樱花

题意:求方程 1/X+1/Y=1/(N!) 的正整数解的组数,其中N≤10^6. 设n!=z,y=z+d 1/x+1/y=1/z 1/x+1/(z+d)=1/z (x+z+d)/(x*z+dx)=1/z z(x+z+d)=x*z+dx z^2+dz=dx x=z^2/d+z 所以只要求有z^2有多少约数(即d的集合元素个数)即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000003 4 #define mo 1

【Copy自某谷题解】P1445 【[Violet]樱花】

做了题还是忍不住要写一发题解,感觉楼下的不易懂啊. 本题解使用latex纯手写精心打造. 题意:求\(\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\)的正整数解总数. 首先,不会线筛素数的先去做下LuoguP3383. 开始推导. \[\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\] 那么\(\frac{1}{x}\)和\(\frac{1}{y}\)肯定是小于\(\frac{1}{n!}\)的.所以\(x\)和\(y\)肯定都是大于\(n!

Bzoj2721 [Violet]樱花(筛法)

题面 题解 首先化一下式子 $$ \frac 1x+\frac 1y=\frac 1{n!} \Rightarrow \frac {x+y}{xy}=\frac 1{n!} \Rightarrow (x+y)n!=xy \\ \Rightarrow(n!-x)+(n!-y)=(n!)^2 $$ 看到最后一个式子,由于$n!$是唯一确定的,所以只要确定了$x$,$y$也是确定的,而且是唯一确定的一组$(x,y)$. 根据唯一分解定理,$n!=p_1^{k_1}p_2^{k_2}...p_m^{k_

Luogu1445 [Violet]樱花

题面 题解 $$ \frac 1x + \frac 1y = \frac 1{n!} \\ \frac{x+y}{xy}=\frac 1{n!} \\ xy=n!(x+y) \\ xy-n!(x+y)=0 \\ (x-n!)(y-n!)=(n!)^2 \\ $$ 因为确定$(x-n!),(y-n!)$就能确定$x,y$,所以答案就是$d((n!)^2)$ 代码 #include<cstdio> #include<cstring> #include<cctype> #in

解题报告:luogu P1445

题目链接:P1445 [Violet]樱花 数学题真的不会了,只推出了浅显的一步,真的菜. 易得到: \[xy=(x+y)n! \] 移项然后两边同时间上\((n!)^2\),构造平方数: \[(n!)^2=(n!)^2+(x+y)n!-xy \] 右边十字相乘因式分解: \[(n!)^2=(n!-x)(n!-y) \] 设\(a=n!-x,b=n!-y\),那么: \[(n!)^2=ab \] 显然\(a,b\)为\((n!)^2\)的因子,且\(a,b\)与\(x,y\)一一对应,那么我们只

【筛法求素数】【质因数分解】bzoj2721 [Violet 5]樱花

http://www.cnblogs.com/rausen/p/4138233.html #include<cstdio> #include<iostream> using namespace std; #define MOD 1000000007 int n; bool Not[1000001]; int pr[1000001],e,ci[1000001]; void shai() { Not[1]=1; for(int i=2;i<=1000;++i) if(!Not[i

2721: [Violet 5]樱花|约数个数

先跪一发题目背景QAQ 显然x,y>n!,然后可以设y=n!+d 原式子可以化简成 x=n!2d+n! 那么解的个数也就是n!的因子个数,然后线性筛随便搞一搞 #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<set> #include<ma

BZOJ2721 [Violet 5]樱花

先令n! = a: 1 / x + 1 / y = 1 / a  =>  x = y * a / (y - a) 再令 k = y - a: 于是x = a + a ^ 2 / k  =>  k | a ^ 2 故等价于求a ^2的约数个数 素数筛一下什么的就好了嘛 1 /************************************************************** 2 Problem: 2721 3 User: rausen 4 Language: C++ 5

【bzoj2721】[Violet 5]樱花 数论

题目描述 输入 输出 样例输入 2 样例输出 3 题解 数论 设1/x+1/y=1/m,那么xm+ym=xy,所以xy-xm-ym+m^2=m^2,所以(x-m)(y-m)=m^2. 所以解的数量就是m^2的约数个数. 所以只需要算出n!中每个素数的出现次数即可. 我们可以先快筛出1~n的素数,然后考虑每个素数出现的次数. 而p出现的次数为包含p^1的数的个数+包含p^2的数的个数+...+包含p^k的数的个数,我们可以迭代来求. 最后把它们乘2加1再乘到一起即可. #include <cstd