2017.9.22 模拟考试 解题报告
来源:互联网 发布:苹果cms多功能手机模板 编辑:程序博客网 时间:2024/05/16 02:01
2017.9.22 模拟考试 解题报告
T1
T1写写看看,一会就发现规律了,然后,除法分块,徐队说:“开莫比乌斯函数,sigma什么的一定会考除法分块”,这道题在洛谷上就叫 约数和
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define LL long longinline LL calc(int n){ LL l=1,r,a,ret=0; for(;l<=n;l=r+1){ a=n/l;//l,r 是区间的左右端点 a代表连续的等差的序列的被用次数 r=n/a; ret+=(r-l+1)*(r+l)*0.5*a; } return ret;}int main(){ freopen("A.in","r",stdin); freopen("A.out","w",stdout); int x,y; cin>>x>>y; cout<<calc(y)-calc(x-1); fclose(stdin);fclose(stdout); return 0;}
等差序列求和公式
Sn=(a1+an)*n*0.5;
再详细说明一下a含义
举个栗子:
X=1,Y=12,Ans=sigma f(i)
1 2 3 4 5 6 7 8 9 10 11 12
12 6 4 3 2 2 1 1 1 1 1 1
第一个等差数列是l=1,r=1,a=12,意思就是说1作为因数贡献了12次
5、6下面对应都是2
5、10、6、12
该等差数列用了两次,恩,应该说的很明白了,当i越大的时候等差数列的长度越长,效率越高。
T2
UVa11440 原题
思路:ϕ(m!)表示小于m!并与m!互质的个数,而与m!互质的个数,他的质因子肯定不包含1-m,因此就是满足条件的。然后对于这题而言,则是要求n!中,不与m!互质的个数,答案取模100000007
求kn中与n互质的个数,答案为kϕ(n)。
ϕ(n)表示1-n中与n互质的个数,那么由此考虑[n + 1, 2n], [2n + 1, 3n]…这每个区间中的每个数字都等于1-n中数字加上kn,对于原来就与n不互质的个数,加上n仍会有一个质因子重复,所以仍然不行,那么对于原来互质的数x,gcd(x, n) = 1,那么可知gcd(x + kn, n) = 1,仍然是互质的,所以每隔n的区间与n互质的个数是相同的,所以答案kϕ(n)
所以对于这道题目,答案就变成了n!/m!ϕ(m!),那么问题只剩下如何求ϕ(m!)。
m!=1*2*3*….*m 所以对m!的阶乘质因数分解得到的因子只能是1-m中的质数。
已知ϕ(n)求法为n∗(1−1/p1)∗(1−1/p2)….(1−1/pn) (p为n的质因子),因此对于m!而言,分子为m!,分母为1 - m所有质数的(1−1/p)之乘积
到这里答案就可以求了,把m!消掉,得到n!/∏(1−1/pi)mod1000000007,先预处理那些表,每次去计算即可
#include<cstdio>using namespace std;#define MAXN 10000001#define Mod 100000007#define LL long longint prime[664580],cnt;bool v[MAXN];LL phifac[MAXN];int main(){ freopen("B.in","r",stdin); freopen("B.out","w",stdout); int n,m; scanf("%d%d",&n,&m); for(int i=2;i<MAXN;++i){ if(!v[i]) prime[++cnt]=i; for(int j=1;j<=cnt;++j){ if(i*prime[j]>=MAXN) break; v[i*prime[j]]=true; if(i%prime[j]==0) break; } } LL ans=0; phifac[1]=1; for(int i=2;i<=m;++i) if(!v[i]) phifac[i]=phifac[i-1]*(i-1)%Mod; else phifac[i]=phifac[i-1]*i%Mod; ans=phifac[m];//现在ans就是phi(m!) for(register int i=m+1;i<=n;++i) ans=ans*i%Mod; //Ans乘上n!/m!倍 printf("%I64d\n",ans-1); return 0;}
上篇代码注释:phifac[m]表示m!的欧拉函数值
解释一下我的递推式:
最原始的方程phi((m-1)!)=(m-1)!((P1-1)/P1) ….((Pk-1)/Pk)
当m是质数时,phi(m!)= m*(m-1)! ((P1-1)/P1) ….((Pk-1)/Pk)((m-1)/m),中间那一块就是phi((m-1)!),==> phi(m!)= m*phi((m-1)!)((m-1)/m),两个蓝色的m再约个分,就得了上面代码里的样子了
当m不是质数的时候,phi(m!)= m*(m-1)! ((P1-1)/P1) ….((Pk-1)/Pk),【因为m不是质数嘛,m肯定可以用p1、p2、、、、pk中的几个质因子表示】,然后中间一坨还是phi((m-1)!),于是乎又有了上面代码中的样子。。
T3
UVa6396 原题
网上有好几份题解是反素数,看了看没看懂,还是看徐队的搜索吧。
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define LL long long int prime[25]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};LL ans,n,C[70][70];void solve(int num,int lim,LL tot,LL now,int last){ if(now>ans) return ; if(tot==n) { ans=now; return ; } if(tot>n || num>20) return ; LL t=1; for(int i=1;i<=lim;++i){ t*=prime[num]; if(now>=ans/t) return; solve(num+1,i,tot*C[last+i][i],now*t,last+i); }}int main(){ freopen("C.in","r",stdin); freopen("C.out","w",stdout); C[0][0]=1; for(int i=1;i<70;++i){ C[i][0]=1; for(int j=1;j<=i;++j) C[i][j]=C[i-1][j]+C[i-1][j-1]; } scanf("%I64d",&n); if(n==1) { printf("1 2\n"); return 0; } ans=(LL)1<<60; solve(1,63,1,1,0); printf("%I64d\n",ans); return 0;}
这道题当时在考场上退出了反着做的正解,哈哈哈,没什么软用。
从最小的质数开始枚举选几个
假设前i-1个种质数用了k个,有Np种方案,第i种质数选a个,
那么前i种质数的方案就有Np*C[k+a][a]
可以理解原来有k个位置,又加了a个位置,有a个数可以放在任意位置
所以前i种的每一种方案都变成C[k+a][a]种
枚举每个质数选几个时,如果上一个质数选了k个,那么这一个质数最多选k个
假设这个质数选了k+1个,那么显然上一个质数选k+1个,这个选k个更优,就是说大质数陪小底数,小大,大小。
- 2017.9.22 模拟考试 解题报告
- 【九度】2014年王道论坛计算机考研机试全真模拟考试解题报告
- 2017.9.4 模拟考试
- 2017.9.5模拟考试
- 2017.9.6模拟考试
- 2017.9.7 模拟考试
- 2017.9.9模拟考试
- 2017.9.15 模拟考试
- 2017.9.14模拟考试
- 2017.9.20 模拟考试
- 模拟考试
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- QML烂笔头记忆
- Leetcode之Plus One 问题
- 文章标题
- Nvidia TX1 安装 ROS 后无法使用 Terminal
- application和page对象
- 2017.9.22 模拟考试 解题报告
- erase c++
- PHP实现单一或者多文件上传功能
- python3 函数写文件路径时,怎么写文件路径才正确
- Douglas-Peucker压缩算法
- 文件
- 主见和索引的区别
- Tian Ji -- The Horse Racing
- Spring学习笔记(五) --- 装配Bean之导入和混合配置