当前位置:   article > 正文

备战蓝桥杯---数论基础刷题1

备战蓝桥杯---数论基础刷题1

数论在蓝桥杯上考的不多,但是这不能否定它的重要性。

1.简单的GCD的应用:

分析一下,由等差数列的性质,个数=(an-a1)/d+1,其中an与a1是固定的,因此我们就是让dmax,我们先排一下序,d就是相邻两个数差的gcd,(注意特判0的情况),同时为了方便求,我们让它与a[0]做差即可(答案显然是对的,可以用欧几里得想一想)

下面是AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=100010;
  4. int a[N],n;
  5. int gcd(int a,int b){
  6. return b? gcd(b,a%b):a;
  7. }
  8. int main(){
  9. cin>>n;
  10. for(int i=0;i<n;i++) scanf("%d",&a[i]);
  11. sort(a,a+n);
  12. int d=0;
  13. for(int i=1;i<n;i++) d=gcd(d,a[i]-a[0]);
  14. if(d) cout<<(a[n-1]-a[0])/d+1;
  15. else cout<<n;
  16. }

2.算数基本定理的应用:

首先我们假设X由a1个质数p1以及a2个质数p2组成,那么我们第一个一定是选一个p1/p2,那么下一个呢?我们要让倍数尽量的小,假如我们乘合数,那么它一定可以分成跟小的质数,假如质数不存在就不选,否则就乘质数,因此我们可以得到一个结论:每次乘p1\p2,因此长度就是a1+a2。

至于个数,就是(a1+a2)!/(a1!*a2!)(高中排列的消序操作)。

这样我们就可以用欧拉筛愉快的AC了:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=(1<<20)+10;
  4. int primes[N],cnt,x;
  5. bool st[N];
  6. int minp[N];
  7. void pp(int n){
  8. for(int i=2;i<=n;i++){
  9. if(!st[i]) minp[i]=i,primes[cnt++]=i;
  10. for(int j=0;primes[j]*i<=n;j++){
  11. st[primes[j]*i]=1;//删的一定是合数
  12. minp[primes[j]*i]=primes[j];
  13. if(i%primes[j]==0) break;//prime[j]一定小于i的最小质因子,保证删合数一定是用其最小质因子,也保证每一个合数一定被删
  14. }
  15. }
  16. }
  17. int main(){
  18. pp(N-1);
  19. int fact[30],sum[N];
  20. while(scanf("%d",&x)!=-1){
  21. int k=0;
  22. int tot=0;
  23. while(x>1){
  24. int p=minp[x];
  25. fact[k]=p,sum[k]=0;
  26. while(x%p==0){
  27. x/=p;
  28. tot++;
  29. sum[k]++;
  30. }
  31. k++;
  32. }
  33. long long ans=1;
  34. for(int i=1;i<=tot;i++) ans*=i;
  35. for(int i=0;i<k;i++){
  36. for(int j=1;j<=sum[i];j++){
  37. ans/=j;
  38. }
  39. }
  40. cout<<tot<<" "<<ans<<endl;
  41. }
  42. }

3.DFS+约数定理+剪枝:

首先对于一个数,它的正约数之和为(1+p1+p1^2+...)(1+p2+p2^2...)(.....)=s

我们发现这样的数其实很少,于是我们考虑DFS+剪枝:

我们每一轮DFS去枚举p以及幂,若整除则枚举下一层,那么如何剪枝?

我们不妨特判(把表达式分一下类),我们发现当a1==1时S=1+Pi,即S-1一定是质数,否则的话一定是偶数(提一个p).

假如S-1为质数,我们就可以得到答案了。

否则,S-1=(1+pi)(1+pj+..)(..)或(1+pi+pi^2)....

对于第一种pi*pj<pi^2,因此我们只要枚举到根号S即可。

这样子就巧妙地从枚举p从2---S到了根号S。

下面是AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=50000;
  4. int primes[N],cnt,x,len,ans[N];
  5. bool st[N];
  6. int minp[N];
  7. void pp(int n){
  8. for(int i=2;i<=n;i++){
  9. if(!st[i]) minp[i]=i,primes[cnt++]=i;
  10. for(int j=0;primes[j]*i<=n;j++){
  11. st[primes[j]*i]=1;//删的一定是合数
  12. minp[primes[j]*i]=primes[j];
  13. if(i%primes[j]==0) break;//prime[j]一定小于i的最小质因子,保证删合数一定是用其最小质因子,也保证每一个合数一定被删
  14. }
  15. }
  16. }
  17. bool check(int x){
  18. if(x<N) return !st[x];
  19. for(int i=0;primes[i]<=x/primes[i];i++){
  20. if(x%primes[i]==0) return 0;
  21. }
  22. return 1;
  23. }
  24. void dfs(int last,int po,int s){
  25. if(s==1){//完成
  26. ans[len++]=po;
  27. return;
  28. }
  29. if(s-1>(last<0?1:primes[last])&&check(s-1)){
  30. ans[len++]=po*(s-1);//完成但是不唯一,因此不return
  31. }
  32. for(int i=last+1;primes[i]<=s/primes[i];i++){//防止暴int
  33. int p=primes[i];
  34. for(int j=1+p,t=p;j<=s;t*=p,j+=t){
  35. if(s%j==0) dfs(i,po*t,s/j);
  36. }
  37. }
  38. }
  39. int main(){
  40. pp(N-1);
  41. int s;
  42. while(cin>>s){
  43. len=0;
  44. dfs(-1,1,s);//上一次的下标,当前正确数,剩余的数。
  45. cout<<len<<endl;
  46. if(len){
  47. sort(ans,ans+len);
  48. for(int i=0;i<len;i++){
  49. printf("%d ",ans[i]);
  50. }
  51. cout<<endl;
  52. }
  53. }
  54. }

4.扩展欧几里得算法的简单应用:

具体内容已经写过,这里就不介绍了,这里就放几张图当复习(这个感觉更好理解):

x+bd=y(mod n)

-an+bd=y-x,其中n,d固定,y-x也是常数,我们只要看看y-x是否是gcd的倍数即可。

答案是b=b0+k*n/gcd(n,d)即b0mod(n/gcd(n,d))

下面是AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. LL exgcd(LL a,LL b,LL &x,LL &y){
  5. if(!b){
  6. x=1,y=0;
  7. return a;
  8. }
  9. LL d=exgcd(b,a%b,y,x);
  10. y-=a/b*x;
  11. return d;
  12. }
  13. int main(){
  14. int t;
  15. cin>>t;
  16. while(t--){
  17. LL n,d,x,y,a,b;
  18. scanf("%lld%lld%lld%lld",&n,&d,&x,&y);
  19. int gcd=exgcd(n,d,a,b);
  20. if((y-x)%gcd) cout<<"Impossible"<<endl;
  21. else{
  22. b*=(y-x)/gcd;
  23. n/=gcd;
  24. printf("%lld\n",(b%n+n)%n);
  25. }
  26. }
  27. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/355038?site
推荐阅读
相关标签
  

闽ICP备14008679号