【题】【数论(拓欧求逆元)、前缀和】NKOJ 3683 沙拉公主的困惑
来源:互联网 发布:行业协会 知乎 编辑:程序博客网 时间:2024/04/30 17:04
NKOJ 3683 沙拉公主的困惑
时间限制 : - MS 空间限制 : 265536 KB
评测说明 : 时限:1500ms
问题描述
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
输入格式
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n
输出格式
共T行,对于每一对N,M,输出1至N!中与M!互质的数的数量对R取模后的值
样例输入 1
1 11
4 2
样例输出 1
1
样例输入 2
5 4421
4 1
4 3
6 2
6 3
6 6
样例输出 2
24
8
360
240
192
思路:
根据题目描述,即求n!中与m!互质的数的数目;
(结论1:)若[1,a]中有k个数与a互质,即phi[a]=k;则[k* a+1,k*a+a]中与a互质的数的数目也为phi[a];
则,可得:对于两个正整数x和y,如果x整除y,那么1~y中与x互质的数的个数为(y/x)* phi[x]。
因为n!为m!的整倍数,题目即转换为求n!/m!*phi[m!]%r;
因为phi[m!]=m!(1-1/p1) (1-1/p2)…… *(1-1/pk);
则原式= n!(1-1/p1) (1-1/p2)…… *(1-1/pk)%r
(结论2:)(1-1/p1)%r* (1-1/p2)%r……* (1-1/pk)%r==(p1-1)/p1%r* (p2-1)/p2%r……(pk-1)/pk%r==(p1-1) p1(逆元)%r* (p2-1)* p2(逆元)%r……* (pk-1)* pk(逆元)%r
所以原式=n!%r* (p1-1)* p1(逆元)%r* (p2-1)* p2(逆元)%r……* (pk-1)*pk(逆元)%r
上式中p1~pk为m!的质因数,且m!的因数为 1、2、3…m
所以:(结论3:)m!的所有质因数就是所有不超过m的质数
即p1~pk为m以内的质数;
优化:
1、因为有多组数据,所以用前缀数组预处理,处理上限为所有m、n中最大的一个,而并非题目上限10000000
预处理n!%r及(p1-1)* p1(逆元)%r* (p2-1)* p2(逆元)%r……* (pk-1)*pk(逆元)%r,因为求最大的一组时m、n时需递推计算。若不预处理则会重复计算。
2、求逆元用拓欧(费马超时QAQ) 3、(结论4:)long long 范围的取模乘法才用快速乘法,int范围转换为long long即可:(ll)a*b%c(不然也是超时QAQ)**
3、(结论4:)long long 范围的取模乘法才用快速乘法,int范围转换为long long即可:(ll)a*b%c(不然也是超时QAQ)
代码:
#include<cstdio>#include<iostream>using namespace std;const int need=10000003;#define ll long longint t,r,nn=0,mm=0,an[need],am[need];/*an[i]表示n!%r,am[i]表示小于i的所有质数p1、p2、……pk的(p1-1)* p1(逆元)%r* (p2-1)* p2(逆元)%r……* (pk-1)*pk(逆元)%r*/int n[need],ni[need];bool zhi[need];void gcd(int a,int b,int &x,int &y){ if(b==0) { x=1,y=0; return; } int x1,y1; gcd(b,a%b,x1,y1); x=y1,y=(x1-(a/b*y1));}int ni_(int a){ int x,y; gcd(a,r,x,y); return (ll)((x+r)%r)*(a-1)%r; /*返回(a-1)*a(逆元)%r*/}int main(){ scanf("%d%d",&t,&r); for(int i=1;i<=t;i++) { scanf("%d%d",&an[i],&am[i]); if(an[i]>nn) nn=an[i]; if(am[i]>mm) mm=am[i]; } int cnt=0; n[1]=1; for(int i=2;i<=nn;i++) n[i]=((ll)n[i-1]*i)%r; ni[1]=1; for(int i=2;i<=mm;i++) { if(zhi[i]==false) { ni[i]=(ll)ni_(i)*ni[i-1]%r; for(int j=i*2;j<=mm;j+=i) zhi[j]=true; } else ni[i]=ni[i-1]; } for(int i=1;i<=t;i++) { int ans=(ll)n[an[i]]*ni[am[i]]%r; printf("%d\n",ans); }}
- 【题】【数论(拓欧求逆元)、前缀和】NKOJ 3683 沙拉公主的困惑
- [BZOJ2186][Sdoi2008]沙拉公主的困惑(数论)
- [bzoj2186][Sdoi2008]沙拉公主的困惑(数论)
- [BZOJ2186][SDOI2008]沙拉公主的困惑(数论)
- 【bzoj2186】【sdoi2008】【沙拉公主的困惑】【数论】
- 【SDOI2008】【BZOJ2186】【沙拉公主的困惑】【题解】【数论】
- BZOJ 2186 SDOI2008 沙拉公主的困惑 数论
- BZOJ 2186 SDOI 2008 沙拉公主的困惑 数论
- BZOJ 2186: [Sdoi2008]沙拉公主的困惑| 数论
- 【bzoj2186】[Sdoi2008]沙拉公主的困惑 数论 线性筛逆元
- bzoj 2186: [Sdoi2008]沙拉公主的困惑 数论
- bzoj 2186: [Sdoi2008] 沙拉公主的困惑 (数论,逆元)
- bzoj 2186: [Sdoi2008]沙拉公主的困惑 (线性筛+数论)
- 沙拉公主的困惑 cash
- BZOJ2186沙拉公主的困惑
- bzoj2186沙拉公主的困惑
- [Sdoi2008]沙拉公主的困惑
- [SDOI2008]沙拉公主的困惑
- [SCU 4515] 又见背包 (可行性背包DP)
- java操作hdfs(上传、下载、查询)
- leetcode笔记--Burst Balloons
- Linux下FastDFS图片服务器的搭建
- 指尖上的电商---(10)SolrAdmin中添加多核
- 【题】【数论(拓欧求逆元)、前缀和】NKOJ 3683 沙拉公主的困惑
- 数据库故障恢复修复指南
- Java枚举
- JSON解析器
- Android通过第三方登录理解oauth2.0机制
- UIView的layoutSubviews和drawRect方法何时调用
- 指尖上的电商---(11)Windows平台部署SolrCloud
- Lua Day1
- 性能测试利器HyperPacer的学习视频前三期