1624 Violet 5 樱花(Bzoj2721 LOJ10202 LUOGU1445 提高+/省选-) 交叉相乘 阶乘质因数分解技巧 约数个数计算

总目录

在线测评地址(ybt)

在线测评地址(LOJ)

在线测评地址(LUOGU)

1.交叉相乘 阶乘质因数分解技巧 约数个数计算

ybt

通过

测试点结果内存时间
测试点1答案正确604KB3MS
测试点2答案正确612KB4MS
测试点3答案正确616KB2MS
测试点4答案正确632KB2MS
测试点5答案正确948KB2MS
测试点6答案正确1040KB2MS
测试点7答案正确1932KB4MS
测试点8答案正确3952KB8MS
测试点9答案正确4784KB9MS

LOJ

LUOGU

只看题目,没有任何感觉,还是要模拟一番,将方程两同时乘以n!xy,方程变成如下乘积形式,

n!(x+y)=xy

n=1时,x+y=xy
y=x/(x-1)
x=2,y=2
只有这种情况

n=2时,2(x+y)=xy
y=2x/(x-2)
x=3,y=6 因x,y等价,x=6,y=3也行
x=4,y=4
共3种情况

n=3时,6(x+y)=xy
y=6x/(x-6)
x=7,y=42 因x,y等价,x=42,y=7也行
x=8,y=24 因x,y等价,x=24,y=8也行
x=9,y=18 因x,y等价,x=18,y=9也行
x=10,y=15 因x,y等价,x=15,y=10也行
x=12,y=12 因x,y等价,x=12,y=12也行
共10种情况

手算太麻烦,程序打表吧

打表前,重新审视了上述模拟。发现最后一对特征,

x=n!*2,y=x

打表代码如下:
 

#include <bits/stdc++.h>
using namespace std;
int n[20];
int main(){
	int N,x,y,i,z;
	scanf("%d",&N);
	printf("%d\n",N);
	n[0]=1;
	for(i=1;i<=N;i++)n[i]=n[i-1]*i;
	for(x=n[N]+1;x<=n[N]*2;x++){
		z=n[N]*x%(x-n[N]);
		if(z==0){
			y=n[N]*x/(x-n[N]);
			printf("x=%d y=%d\n",x,y);
		}
	}
	return 0;
}

上述打表代码对应的输入输出数据如下:

2
2
x=3 y=6
x=4 y=4

3
3
x=7 y=42
x=8 y=24
x=9 y=18
x=10 y=15
x=12 y=12


4
4
x=25 y=600
x=26 y=312
x=27 y=216
x=28 y=168
x=30 y=120
x=32 y=96
x=33 y=88
x=36 y=72
x=40 y=60
x=42 y=56
x=48 y=48

5
5
x=121 y=14520
x=122 y=7320
x=123 y=4920
x=124 y=3720
x=125 y=3000
x=126 y=2520
x=128 y=1920
x=129 y=1720
x=130 y=1560
x=132 y=1320
x=135 y=1080
x=136 y=1020
x=138 y=920
x=140 y=840
x=144 y=720
x=145 y=696
x=150 y=600
x=152 y=570
x=156 y=520
x=160 y=480
x=165 y=440
x=168 y=420
x=170 y=408
x=180 y=360
x=184 y=345
x=192 y=320
x=195 y=312
x=200 y=300
x=210 y=280
x=216 y=270
x=220 y=264
x=240 y=240

总体感觉是:

加法,乘法 首选。

加法,除法 尽量不选。

看了思路,自己想,确实还达不到这个境界,但代码没看。

n!质因数分解如下,以10!作为说明

区间[2,10]内质因数有2,3,5,7

质因数是2的幂次计算
10/2+10/4+10/8=5+2+1=8
说明如下:
10*9*8*7*6*5*4*3*2*1中能整除2的有10,8,6,4,2共计5个数
10*9*8*7*6*5*4*3*2*1中能整除2^2的有8,4共计2个数
10*9*8*7*6*5*4*3*2*1中能整除2^3的有8共计1个数

质因数是3的幂次计算
10/3+10/9=3+1=4

质因数是5的幂次计算
10/5=2


质因数是7的幂次计算
10/7=1

故:
10!=2^8*3^4*5^2*7^1

10!=3628800
2^8*3^4*5^2*7^1=3628800


n=2时,输出3
过程如下:
2/2=1,(2*1+1)=3

n=3时,输出9
过程如下:
质因数2,3/2=1
质因数3,3/3=1
(2*1+1)*(2*1+1)=9


n=4时,输出9
过程如下:
质因数2,4/2+4/4=3
质因数3,4/3=1
(2*3+1)*(2*1+1)=21

完美切合。

按上述思想编写的AC代码如下:

#include <bits/stdc++.h>
#define maxn 1000010
#define mod 1000000007
#define LL long long
using namespace std;
int b[maxn],prime[maxn],tot;
void linear(int x){
	int i,j;
	for(i=2;i<=x;i++)b[i]=0;
	for(i=2;i<=x;i++){
		if(b[i]==0)prime[++tot]=i;
		for(j=1;j<=tot&&i*prime[j]<=x;j++){
			b[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main(){
	int n,i,j,c;
	LL num=1,d;
	scanf("%d",&n);
	linear(n);
	for(i=1;i<=tot;i++){
		d=1,c=0;
		for(j=1;;j++){
			d*=prime[i];
			if(d>n)break;
			c+=n/d;
		}
		num=num*(2*c+1)%mod;
	}
	printf("%lld\n",num);
	return 0;
}

提高+/省选- 习得了什么?

交叉相乘 阶乘质因数分解技巧 约数个数计算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值