博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
和Leo一起做爱数学的好孩子之 CERC2017 Faulty Factory 阶乘谜题
阅读量:4360 次
发布时间:2019-06-07

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

给定n,质数p和一个目标余数r

你需要改变n的阶乘中的一个数字,使得其积模p余r。

感觉不能融会贯通

我以为是个EXGCD的神仙题

首先n看似很大,但是明显n并不是完全有用

2*p<=n时若余数不为0则无解

对于p<n有:

(\prod_{i}^{n}i)/p\equiv r (mod=p)这个明显是一个不定方程,算出最小解再判断和p的大小关系就好了

但是n<p怎么办?

由于这个不超过1e7我认为直接枚举变的暴力EXGCD

O(log_{\frac{1+\sqrt{5}}{2}}N)但很明显这是不能A掉的(虽然开了3s)

这个时候思考BSGS(北上广深新一线算法)

我们有一个在同余方程移位的操作

(\prod_{i-1}^{n}i)/j*x\equiv r(mod=p)等价于x\equiv Inv(\prod_{i=1}^{n}i)*j*r (mod=p)

如果线性预处理逆元这是O1查询的

那么就A了

#include
#include
#include
#include
#include
using namespace std;#define LL long longLL n,p,r;LL Check(LL Id,LL sum,LL mod){ LL ret=1; for(int i=1;i<=n;++i){ if(i==Id)ret=ret*sum%mod; else ret=ret*i%mod; } return ret;}void Solve50(){ for(int i=2;i<=n;++i){ for(int j=1;j
=2*p){ if(!r)cout<
<<" "<<1; else cout<<-1<<" "<<-1; return; } F[0]=1; if(p>n){ LL x,y; if(!r){ cout<<-1<<" "<<-1<<'\n'; return ; } for(int i=1;i<=n;++i){ F[i]=F[i-1]*i%p; } EXGCD(x,y,F[n],p); LL Inv=(x+p)%p; for(int i=2;i<=n;++i){ LL tmp=Inv*i%p*r%p; if(tmp
>n>>p>>r; if(n<=500){ Solve50(); } else{ Solve100(); } return 0;}

 

转载于:https://www.cnblogs.com/Leo-JAM/p/10079117.html

你可能感兴趣的文章
乐观锁实现
查看>>
Spring 事务小结
查看>>
AI入门基础之界面的认识
查看>>
平面设计之CDR文本绘图工具总结
查看>>
ps入门之界面各个属性的认识
查看>>
cdr入门之复制对象的几种方式
查看>>
cdr入门之网状工具总结
查看>>
Delphi 实现Ping命令
查看>>
flutter布局-1-column
查看>>
深入Delphi下的DLL编程
查看>>
Flutter布局2--Align
查看>>
Flutter布局3-----Center
查看>>
Flutter布局4--Row
查看>>
Flutter布局5---Container
查看>>
Flutter布局----弹性布局 (Flex)
查看>>
简单算法考题记录
查看>>
Leetcode题解记录
查看>>
C++ 基本知识整理
查看>>
操作系统基本知识整理
查看>>
计算机网络基本知识整理
查看>>