博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

欧拉函数学习笔记

如何求欧拉函数~转载

三、欧拉函数

# [SDOI2008] 沙拉公主的困惑

## 题目描述

大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为 1 到 N 的阶乘,但是,政府只发行编号与 M! 互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于数量可能非常大,你只需计算出答案对 R 取模后的结果即可。

 

## 输入格式

第一行为两个整数 T 和 R,其中 T 为该组中测试数据数目,R 为模数。

接下来 T 行,每行一对整数 N 和 M,具体意义见题目描述。

 

## 输出格式

共 T 行,对于每一对 N 和 M,输出 [1,N!] 中与 M! 互质的数的数量对 R 取模后的值。

 

## 样例 #1

### 样例输入 #1

```
1 11
4 2
```

### 样例输出 #1

```
1
```

 

## 提示

对于 100% 的数据,1≤M≤N≤107,1≤T≤104,2≤R≤109+10 且 R 为质数。

 

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000010
typedef long long ll;
int R,N,M,cntp[maxn],idx=0;
int jc[maxn],inv[maxn],g[maxn],ph[maxn];
bool pr[maxn];
void is_prime()//埃拉托色尼筛法
{
for(int i=3;i<=1e7;i+=2)
if(pr[i])
{
cntp[++idx]=i;
if(1ll*i*i>1e7) continue;
for(int j=i*i;j<=1e7;j+=i)
pr[j]=0;
}
}
int qpow(int x,int p)
{
int res=1;
for( ;p;p>>=1,x=1ll*x*x%R)
if(p&1) res=1ll*res*x%R;
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin>>T>>R;
pr[2]=1;//筛质数
cntp[++idx]=2;//少了这步,遗臭千年
for(int i=3;i<=1e7;i+=2) pr[i]=1;
is_prime();//我的埃筛怎么那么容易出bug
jc[0]=jc[1]=inv[0]=inv[1]=1;//思考为什么inv[0]=1 : 定义(0!)=1
g[0]=g[1]=1;
for(int i=2;i<=1e7;i++)
{
int x=i;
while(x%R==0) x/=R;//把R除去
jc[i]=1ll*jc[i-1]*x%R;//线性求阶乘
// inv[i]=1ll*(R-R/x)*inv[R%x]%R;//线性求逆元
x=i-pr[i];//根据素数为i-1,合数为i
while(x%R==0) x/=R;//把R除去
g[i]=1ll*g[i-1]*x%R;//phi(M!)
}
while(T--)
{
cin>>N>>M;
if(N/R>M/R) cout<<"0"<<'\n';//特判:N!中的R因子比M!多
else cout<<1ll*jc[N]*g[M]%R*qpow(jc[M],R-2)%R<<'\n';
// else cout<<1ll*jc[N]*inv[M]%R*g[M]%R<<'\n';
}
return 0;
}

下次再打。。。

posted @   珂兰洁  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示