【BZOJ 2186】 2186: [Sdoi2008]沙拉公主的困惑 (欧拉筛,线性求逆元)

本文详细解答了[Sdoi2008]沙拉公主的困惑问题,通过数学方法求解特定范围内与某数互质的数的数量,并提供了完整的代码实现。
部署运行你感兴趣的模型镜像

2186: [Sdoi2008]沙拉公主的困惑

Description

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

Input

第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n

Output

共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值

Sample Input

1 11
4 2

Sample Output

1

数据范围:
对于100%的数据,1 < = N , M < = 10000000

HINT

Source

 

 

【分析】

  本来做这题是找信心,然而。。

  首先我们知道 如果x与y互质,那么x+y与y也互质。

  所以只需要求$\phi(m!)* \dfrac{n!}{m!} $

  问题转换成求$\phi(m!)$

  我们知道一种求法,就是把$m!$分解质因数,对于每个素数乘上一个$\dfrac{p-1}{p}$

  显然<=m的素数就是$m!$的分解质因数。

 

  中间要用到的线性求逆元:

  ny[1]=1;

  for(int i=2;i<=Maxn-10;i++) ny[i]=(R-R/i*ny[R%i])%R;

 

  

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 10000010
 8 #define LL long long
 9 
10 int R;
11 
12 int mul(int x,int y)
13 {
14     LL K1=(LL)x,K2=(LL)y;
15     K1=(K1*K2)%R;
16     return (int)K1;
17 }
18 
19 int pri[Maxn],pl;
20 int ny[Maxn];
21 bool vis[Maxn];
22 void init()
23 {
24     for(int i=2;i<=Maxn-10;i++)
25     {
26         if(!vis[i]) pri[++pl]=i;
27         for(int j=1;j<=pl;j++)
28         {
29             LL K1=(LL)i,K2=(LL)pri[j];
30             K1=K1*K2;
31             if(K1>Maxn) break;
32             vis[K1]=1;
33             if(i%pri[j]==0) break;
34         }
35     }
36 }
37 
38 int A[Maxn],B[Maxn];
39 void get_ans()
40 {
41     A[1]=1;
42     for(int i=2;i<=Maxn-10;i++)
43     {
44         A[i]=mul(A[i-1],i);
45     }
46     int now=1;
47     B[1]=1;
48     for(int i=2;i<=Maxn-10;i++)
49     {
50         B[i]=B[i-1];
51         while(pri[now]<=i&&now<=pl)
52         {
53             B[i]=mul(mul(pri[now]-1,ny[pri[now]]),B[i]);
54             // B[i]=((B[i]*(pri[now]-1)%R)%R)*ny[pri[now]];
55             // B[i]%=R;
56             now++;
57             if(now==pl) break;
58         }
59     }
60 }
61 
62 int main()
63 {
64     int T;
65     scanf("%d%d",&T,&R);
66     // memset(vis,0,sizeof(vis));
67     for(int i=1;i<=Maxn-10;i++) vis[i]=0;
68     init();
69     ny[1]=1;
70     for(int i=2;i<=Maxn-10;i++) ny[i]=mul(R-R/i,ny[R%i]);
71     
72     get_ans();
73     while(T--)
74     {
75         int n,m;
76         scanf("%d%d",&n,&m);
77         int ans=mul(A[n],B[m]);
78         printf("%d\n",ans);
79     }
80     return 0;
81 }
View Code

这道恶心题又卡空间 又卡时间。

 

2017-02-13 13:48:22

转载于:https://www.cnblogs.com/Konjakmoyu/p/6393436.html

您可能感兴趣的与本文相关的镜像

Linly-Talker

Linly-Talker

AI应用

Linly-Talker是一款创新的数字人对话系统,它融合了最新的人工智能技术,包括大型语言模型(LLM)、自动语音识别(ASR)、文本到语音转换(TTS)和语音克隆技术

MATLAB代码实现了一个基于多种智能优化算法优化RBF神经网络的回归预测模型,其核心是通过智能优化算法自动寻找最优的RBF扩展参数(spread),以提升预测精度。 1.主要功能 多算法优化RBF网络:使用多种智能优化算法优化RBF神经网络的核心参数spread。 回归预测:对输入特征进行回归预测,适用于连续值输出问题。 性能对比:对比不同优化算法在训练集和测试集上的预测性能,绘制适应度曲线、预测对比图、误差指标柱状图等。 2.算法步骤 数据准备:导入数据,随机打乱,划分训练集和测试集(默认7:3)。 数据归一化:使用mapminmax将输入和输出归一化到[0,1]区间。 标准RBF建模:使用固定spread=100建立基准RBF模型。 智能优化循环: 调用优化算法(从指定文件夹中读取算法文件)优化spread参数。 使用优化后的spread重新训练RBF网络。 评估预测结果,保存性能指标。 结果可视化: 绘制适应度曲线、训练集/测试集预测对比图。 绘制误差指标(MAE、RMSE、MAPE、MBE)柱状图。 十种智能优化算法分别是: GWO:灰狼算法 HBA:蜜獾算法 IAO:改进天鹰优化算法,改进①:Tent混沌映射种群初始化,改进②:自适应权重 MFO:飞蛾扑火算法 MPA:海洋捕食者算法 NGO:北方苍鹰算法 OOA:鱼鹰优化算法 RTH:红尾鹰算法 WOA:鲸鱼算法 ZOA:斑马算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值