博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【数论】【欧拉函数】【筛法求素数】【乘法逆元】【快速幂取模】bzoj2186 [Sdoi2008]沙拉公主的困惑...
阅读量:6853 次
发布时间:2019-06-26

本文共 2352 字,大约阅读时间需要 7 分钟。

http://www.cnblogs.com/BLADEVIL/p/3490321.html

http://www.cnblogs.com/zyfzyf/p/3997986.html

翻了翻题解,这两个合起来比较明白……

题意:求1~n!中与m!互质的数的数量(mod R)。

 

∵由欧几里得算法得gcd(a,b)=gcd(b,a%b)

∴gcd(a+b,b)=gcd(b,(a+b)%b)=gcd(b,a) 即 gcd(a,b)=gcd(a+b,b)

推广:gcd(a,b)=gcd(a+k*b,b)

∴若a与b互质,则a+k*b也与b互质

 

令n=5,m=4,则n!=120,m!=24

符合题意的数有以下:

5 29 53 77 101

7 31 55 79 103

11 35 59 83 107

13 37 61 85 109

17 41 65 89 113

19 43 67 91 115

23 47 71 95 119

∴若x(x<n!)与m!互质,则x+m!*k也和m!互质,根据我们刚才推出的性质,仔细观察,发现 x 在 mod m!的剩余系中恰好有n!/m!个数符合题意。

∴观察上表的第一列,我们只需考虑小于m!的数中与n!互质的数。

∴这样的数恰好有φ(m!)个

∴答案为φ(m!)*(n!/m!)

但是这样仍然超出了我们能承受的时间复杂度。

∴ans=φ(m!)*(n!/m!)

=m!*((p1-1)/p1)+((p2-1)/p2)+......+((pk-1)/pk)*n!/m!  (p1......pk为m!的质因子,根据阶乘的定义,易证,m!的质因子恰好为<=m的所有质数)

=((p1-1)/p1)+((p2-1)/p2)+......+((pk-1)/pk)*n!

∴我们递推预处理出((p1-1)/p1)+((p2-1)/p2)+......+((pk-1)/pk)和n!即可O(1)地回答每个询问。

在预处理连续乘积的时候,我们要用到快速幂求乘法逆元。

综上,要预处理的是:

①maxm以内的素数

②maxm以内的素数的逆元

③1!~maxn!

④maxm以内的素数的((p1-1)/p1)+((p2-1)/p2)+......+((pk-1)/pk)

 

1 #include
2 #include
3 #include
4 using namespace std; 5 typedef long long ll; 6 ll MOD; 7 int T,n[10001],m[10001],maxn,maxm,Ni[10000001],Fac[10000001],Muls[10000001]; 8 bool unPrime[10000001]; 9 void Shai_Prime()10 {11 unPrime[1]=true;12 for(ll i=2;i<=maxm;i++)13 for(ll j=i*i;j<=maxm;j+=i) unPrime[j]=true;14 }15 ll pow_mod(ll a,ll p,ll MOD)16 {17 if(!p) return 1;18 ll ans=pow_mod(a,p>>1,MOD);19 ans=ans*ans%MOD;20 if((p&1)==1) ans=ans*a%MOD;21 return ans;22 }23 void Init_Ni()24 {25 for(int i=1;i<=maxm;i++)26 if(!unPrime[i])27 Ni[i]=(int)pow_mod(i,MOD-2,MOD);28 }29 void Init_Fac()30 {31 Fac[1]=1;32 for(int i=2;i<=maxn;i++) Fac[i]=(int)((ll)Fac[i-1]*(ll)i%MOD);33 }34 void Init_Muls()35 {36 ll res=1;37 for(int i=1;i<=maxm;i++)38 {39 if(!unPrime[i]) res=((res*(ll)(i-1))%MOD)*(ll)Ni[i]%MOD;40 Muls[i]=res;41 }42 }43 int main()44 {45 scanf("%d",&T); cin>>MOD;46 for(int i=1;i<=T;i++)47 {48 scanf("%d%d",&n[i],&m[i]);49 maxn=max(n[i],maxn);50 maxm=max(m[i],maxm);51 }52 Shai_Prime(); Init_Ni(); Init_Fac(); Init_Muls();53 for(int i=1;i<=T;i++)54 printf("%d\n",(int)((ll)Muls[m[i]]*(ll)Fac[n[i]]%MOD));55 return 0;56 }

 

转载于:https://www.cnblogs.com/autsky-jadek/p/4054971.html

你可能感兴趣的文章
动画的timing-function比较
查看>>
java输出各种学生成绩
查看>>
uva 10020 Minimal coverage (greedy)
查看>>
LA 4973 Ardenia (3D Geometry + Simulation)
查看>>
微信开发学习(二)
查看>>
JS中的“!!”
查看>>
python之MySQL操作
查看>>
radioButton添加试题选项webview(二)
查看>>
Centos7 linux 安装 redis 遇到的几个问题
查看>>
Kohana的请求流
查看>>
Oracle 12c Sharding测试过程中的问题解决
查看>>
Oracle Index 索引监控
查看>>
Elasticsearch2.x 全文检索之——Match转换Bool Query
查看>>
NET联调
查看>>
noi.ac day6t1 queen
查看>>
作业四 任务分解(WBS)
查看>>
eclipse 创建maven 项目 动态web工程完整示例
查看>>
laravel中的命名公约规范及relation N+1问题
查看>>
Convolution of measures and one application
查看>>
逆序对 线段树&树状数组 (重制版)
查看>>