题目的意思大概是求1~N!中和M!互质的数的个数

因为对欧拉函数理解不够深刻所以我是分析得到结果的:

当N<=M的时候显然符合要求的数的个数为0;

当N>M的时候我们要求的是1~N!中不含1 ~M的素因子的的数的个数,结合欧拉函数的推导过程(容斥原理)假设N!在1 ~ M中含有k个素因子,设n=N!,那么符合要求的数的个数就是

n−n/p1−n/p2−...−n/pk+n/p1p2+n/p1p3+...+n/p(k−1)pk−...=n(1−1/p1)(1−1/p2)...(1−1/pk)n-n/p1-n/p2-...-n/pk+n/p1p2+n/p1p3+...+n/p(k-1)pk-...=n(1-1/p1)(1-1/p2)...(1-1/pk)n−n/p1−n/p2−...−n/pk+n/p1p2+n/p1p3+...+n/p(k−1)pk−...=n(1−1/p1)(1−1/p2)...(1−1/pk)
因为我们不能首先求出n的大小再算(如果可以求出n的大小的话那显然直接计算就可以,但是我们必须要模R),在模R的情况下我们应该求出pi的逆元,所以整个过程就是线性筛得到1~M的素数因子以及他们的逆元,然后与N!相乘计算(按照上面的公式)

我的代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<ctime>
#include<climits>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e7+5;
int prime[MAXN];
bool check[MAXN];
int N[MAXN],r[MAXN],ans[MAXN];
int tot;
ll R,n,m;void ex_gcd(int a,int b,int& d,int &x,int &y)
{if(!b) {d=a; x=1; y=0;}else{ex_gcd(b,a%b,d,y,x); y-=(a/b)*x;}
}int getine(int a)
{int x,y,d;ex_gcd(a,R,d,x,y); x=(x%R+R)%R;return x;
}void creat_prime()
{tot=0; r[1]=1; N[1]=1;for(int i=2;i<MAXN;i++){N[i]=(ll)N[i-1]*i%R;if(!check[i]){prime[tot++]=i;r[i]=getine(i);}for(int j=0;j<tot && prime[j]*i<MAXN;j++){check[prime[j]*i]=true;if(i%prime[j]==0) break;}}
}void init()
{ans[1]=1;for(int i=2;i<MAXN;i++){ans[i]=ans[i-1];if(!check[i]) ans[i]=(ll)ans[i]*(i-1)%R*r[i]%R;}
}int main()
{int T;scanf("%d%d",&T,&R);creat_prime();init();while(T--){scanf("%d%d",&n,&m);printf("%d\n",(ll)N[n]*ans[m]%R);}return 0;
}

虽然可以得到正确的答案,但是经过了自己的推导分析,思维质量比较低。根本原因还是对欧拉函数的理解不够深刻。

让我们再来看看欧拉函数的意义:求出1~n中和n互质的数的个数,那么1 ~kn中与n互质的数的个数有多少呢?答案是k*phi[n](结合上面推导也可以发现这个)。为什么是这样呢?

互质即意味着gcd(x,n)=1gcd(x,n)=1gcd(x,n)=1,由最大公约数的性质我们得到gcd(x+kn,n)=1gcd(x+kn,n)=1gcd(x+kn,n)=1即这个数在每次kn+1~(k+1)n中都会出现一次,所以答案是k*phi[n]

回到这个问题:题目要求1~N!中和M!互质的数的个数,那么答案应该是N!/M!*phi[M!],再结合欧拉函数值的求法可以得到上面的过程。

学习了一下递推法求逆元.(递推法求逆元如果不是都要用时间还是慢一点)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<ctime>
#include<climits>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e7+5;
int prime[MAXN];
bool check[MAXN];
int N[MAXN],r[MAXN],ans[MAXN];
int tot;
ll R,n,m;int read()
{int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x;
}void ex_gcd(int a,int b,int& d,int &x,int &y)
{if(!b) {d=a; x=1; y=0;}else{ex_gcd(b,a%b,d,y,x); y-=(a/b)*x;}
}int getine(int a)
{int x,y,d;ex_gcd(a,R,d,x,y); x=(x%R+R)%R;return x;
}void creat_prime()
{tot=0; r[1]=1; N[1]=1;for(int i=2;i<MAXN;i++){N[i]=(ll)N[i-1]*i%R;if(!check[i]){prime[tot++]=i;//r[i]=getine(i);}for(int j=0;j<tot && prime[j]*i<MAXN;j++){check[prime[j]*i]=true;if(i%prime[j]==0) break;}}for(int i=2;i<MAXN&&i<R;i++)r[i]=R-(ll)R/i*r[R%i]%R;
}void init()
{ans[1]=1;for(int i=2;i<MAXN;i++){ans[i]=ans[i-1];if(!check[i]) ans[i]=(ll)ans[i]*(i-1)%R*r[i]%R;}
}int main()
{int T;T=read(); R=read();creat_prime();init();while(T--){n=read(); m=read();printf("%d\n",(ll)N[n]*ans[m]%R);}return 0;
}

BZOJ - 2186 欧拉函数相关推荐

  1. bzoj 2818 欧拉函数

    思路:就是对于某个数q,跟他互质的数p,kp和kq的最大公约数是k,那么这个数能组成的答案的数量就是phi[i]乘以某个质数,且乘积小于n 基于这种思路写下这个代码 #include <cstd ...

  2. BZOJ 4802: 欧拉函数(大数因数分解算法 Pollard_rho 和素数测试算法 Miller_Rabin)

    Description 已知N,求phi(N) Input 正整数N.N<=10^18 Output 输出phi(N) Sample Input 8 Sample Output 4 Soluti ...

  3. bzoj 4805: 欧拉函数求和

    Time Limit: 15 Sec  Memory Limit: 256 MB Submit: 539  Solved: 304 [Submit][Status][Discuss] Descript ...

  4. bzoj 1409 Password 矩阵快速幂+欧拉函数

    可以发现,该数组的mi就是斐波那契数列 所以要矩阵快速幂搞出第n位 但是斐波那契数列上涨的很快,这就需要欧拉定理了 p^phi(q)%q=1(gcd(p,q)==1) p是素数,所以可以用 然后需要5 ...

  5. bzoj 3884: 上帝与集合的正确用法(欧拉函数)

    3884: 上帝与集合的正确用法 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2574  Solved: 1151 [Submit][Status] ...

  6. bzoj 2705: [SDOI2012]Longge的问题(欧拉函数)

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 3077  Solved: 1914 [Submit ...

  7. bzoj 5245: [Fjwc2018]欧拉函数 线段树+bitset

    题意 对于正整数 n,定义欧拉函数 φ(n) 为小于等于 n 且与 n 互质的正整数个数.例如 φ(1) = 1, φ(8) = 4. 给定正整数序列 a1, a2, · · · , an,请依次执行 ...

  8. BZOJ 2818: Gcd区间内最大公约数 为素数的对数(欧拉函数的应用)

    传送门 2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3649 Solved: 1605 [Submit][Status][Dis ...

  9. poj2154-color-polyan次二面体+欧拉函数优化

    N<=1e9,O(nlogn)的做法会超时.从枚举置换转变为枚举轮换长度,然后可以利用欧拉函数,把复杂度变为O(√n * logn) 1 /*-------------------------- ...

最新文章

  1. 【微信小程序之画布】一:canvas组件
  2. 《正则表达式必知必会》读书笔记
  3. 关于Go ROOT 和Go PATH的设置
  4. python小游戏代码大全-Python实现打砖块小游戏代码实例
  5. netcore部署到docker 实现excel生成_Docker部署Redis集群----第七节(docker-redis-sentinel集群实现篇)...
  6. spark rdd reduceByKey示例
  7. python27.dll引起的appcrash_python27.dll错误代码126怎么解决
  8. 博客园培训OOAD的课程概要
  9. 异常检测算法之HBOS
  10. 【bzoj1705】[Usaco2007 Nov]Telephone Wire 架设电话线 dp
  11. 文件的上传、文件的下载、I18N国际化
  12. PCIe规范的扩展:SR-IOV(Single Root I/O virtual)网卡直通技术
  13. JavaScript学习(三十六)—移动的小球
  14. 图像局部特征(四)--FAST-ER角点检测子
  15. sessionid如何产生?由谁产生?保存在哪里?
  16. 2021-08-10 idea 事务的操作
  17. openstack搭建问题
  18. Vue-router路由转发
  19. Excel图表5——旋风图(对称条形图)
  20. torch实现clip by tensor操作

热门文章

  1. 2018091-2 博客作业
  2. 20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行
  3. Spring MVC 返回NULL时客户端用$.getJSON的问题
  4. linux nexus启动_Linux一键部署Nexus 3私服仓库自动化部署脚本
  5. 图片资源 php,php URL图片资源传参生成对应尺寸图片
  6. mysql主从进行扩展_MySQL 主从扩展
  7. java 分贝_java11教程--jhsdb命令
  8. metasploitable2渗透测试
  9. mysql generaton_Mysql 集成随机唯一id mysql unique number generation
  10. python岗位 上海_上海黑马Python24期,平均薪资10150元,16个工作日就业率70.73%