4.18 省选模拟赛 无聊的计算器 CRT EXBSGS EXLucas
算是一道很毒瘤的题目 考试的时候码+调了3h才搞定。
op==1 显然是快速幂。
op==2 有些点可以使用BSGS 不过后面的点是EXBSGS.
这个以前学过了 考试的时候还是懵逼。(当时还是看着花姐姐的题解学的
为了起到再次复习的作用 我决定 再推导一遍。
对于高次同余方程 \(a^x\equiv b(mod p)\) 朴素的BSGS利用是欧拉定理的应用解决的。此时要求(a,p)=1.
考虑解决(a,p)>1的情况 容易发现我们进行一些操作 使得他们互质就可以继续使用EXBSGS了。
当b%p==1时显然x取0 但是当b%p!=1时x有解必然取的时正整数 原式可以变成 \(a^{x-1}\cdot a+kp=b\)
容易发现 当(a,p)|b 等式才有整数解。
当出现上述情况的时候 容易把式子变为 \(a^{x-1}\cdot \frac{a}{(a,p)}\equiv \frac{b}{(a,p)}(mod \frac{p}{(a,p)})\)
可以发现两个式子求解出x后时等价的。
然后如果x和p'还不互质继续下去。直至互质然后解EXBSGS即可。
最后要加回来一直递归下去的次数 可以发现最多递归log层。
值得注意的是再递归的时候如果发现了某一部(a,p)不整除b了 那么还是无解的注意判断。
最后 关于求逆 不是质数了 注意使用exgcd.
op==3.
裸的EXLucas了 也写过很多遍了。值得一提的是 提前预处理跑的是真的快。
const ll MAXN=200010;
ll Q;
ll op,a,b,p,xx,yy;
map<ll,ll>H;
ll y[MAXN],w[MAXN],jc[MAXN],f[MAXN],inv[MAXN],ans[MAXN];
ll flag;
inline void fj(ll x)
{
flag=0;
for(ll i=2;i*i<=x;++i)
{
if(x%i==0)
{
y[++flag]=i;w[flag]=1;
while(x%i==0)
{
x/=i;
w[flag]*=i;
}
}
}
if(x>1)y[++flag]=x,w[flag]=x;
}
inline ll ksm(ll b,ll p,ll mod)
{
ll cnt=1;
while(p)
{
if(p&1)cnt=cnt*b%mod;
b=b*b%mod;p=p>>1;
}
return cnt;
}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void exgcd(ll a,ll b)
{
if(!b){xx=1;yy=0;return;}
exgcd(b,a%b);
ll zz=xx;xx=yy;yy=zz-a/b*yy;
}
inline ll INV(ll a,ll mod)
{
exgcd(a,mod);
return (xx%mod+mod)%mod;
}
inline ll BSGS(ll a,ll b,ll mod)//a^x=b(% mod)
{
a%=mod;b%=mod;
if(b==1)return 0;
H.clear();
ll m=(ll)sqrt(mod*1.0)+1;
ll w1=1;H[b]=0;
rep(1,m,i)
{
w1=w1*a%mod;
ll cc=w1*b%mod;
H[cc]=max(H[cc],i);
}
ll cc=1;
rep(1,m,i)
{
cc=cc*w1%mod;
if(H.find(cc)!=H.end())
return i*m-H[cc];
}
return -1;
}
inline ll exBSGS()
{
a%=p;b%=p;
if(b==1)return 0;
ll k=0;
ll wp=p,w1=1,g;
while((g=gcd(a,wp))>1)
{
if(b%g)return -1;
++k;w1=a/g;b=b/g;wp=wp/g;
b=b*INV(w1,wp)%p;
if(b==1)return k;
}
ll ans=BSGS(a,b,wp);
return ans<0?ans:ans+k;
}
inline ll C(ll a,ll b,ll mod)
{
return ((jc[a]*inv[b]%mod)*(inv[a-b]))%mod;
}
inline void prepare(ll mod)
{
jc[0]=1;
for(ll i=1;i<mod;++i)jc[i]=jc[i-1]*i%mod;
inv[mod-1]=ksm(jc[mod-1],mod-2,mod);
for(ll i=mod-2;i>=0;--i)inv[i]=inv[i+1]*(i+1)%mod;
}
inline ll Lucas(ll a,ll b,ll mod)
{
if(a<b)return 0;
if(a<=mod)return C(a,b,mod);
return (Lucas(a%mod,b%mod,mod)*Lucas(a/mod,b/mod,mod))%mod;
}
inline ll lc(ll x,ll p,ll pp)
{
if(x<=p)return f[x];
ll ww=x/pp;
return ksm(f[pp],ww,pp)*f[x%pp]%pp*lc(x/p,p,pp)%pp;
}
inline ll js(ll x,ll xx,ll xxx,ll mod)
{
ll w=1;
ll cnt=0;
while(x>w)
{
w=w*mod;
cnt+=x/w;
cnt-=xx/w;
cnt-=xxx/w;
}
return cnt;
}
inline void ycl(ll p,ll pp)
{
f[0]=1;
rep(1,pp,i)if(i%p)f[i]=f[i-1]*i%pp;
else f[i]=f[i-1];
}
inline ll solve(ll a,ll b,ll p,ll pp)
{
ll k=js(a,b,a-b,p);
ll ans1,ans2,ans3;
ans1=lc(a,p,pp);
ans2=lc(b,p,pp);
ans3=lc(a-b,p,pp);
ans2=INV(ans2,pp);
ans3=INV(ans3,pp);
ans1=((((ans1*ans2%pp)*ans3)%pp)*ksm(p,k,pp))%pp;
return ans1;
}
inline ll merge()
{
ll an=0;
for(ll i=1;i<=flag;++i)
{
ll M=p/w[i];
ll ww=INV(M,w[i]);
an=(an+((M*ww%p)*ans[i])%p)%p;
}
return an;
}
signed main()
{
//freopen("1.in","r",stdin);
freopen("calculator.in","r",stdin);
freopen("calculator.out","w",stdout);
get(Q);
rep(1,Q,i)
{
get(op);get(a);get(b);get(p);
if(op==1)putl(ksm(a,b,p));
if(op==2)
{
fj(p);ll ww;
if(flag==1&&y[1]==w[1])ww=BSGS(a,b,p);
else ww=exBSGS();
if(ww<0)puts("Math Error");
else putl(ww);
}
if(op==3)
{
swap(a,b);
fj(p);
if(flag==1&&y[1]==w[1])
{
prepare(p);
putl(Lucas(a,b,p));
}
else
{
rep(1,flag,i)
{
ycl(y[i],w[i]);
ans[i]=solve(a,b,y[i],w[i]);
}
putl(merge());
}
}
}
return 0;
}
4.18 省选模拟赛 无聊的计算器 CRT EXBSGS EXLucas的更多相关文章
- 6.18 省选模拟赛 树 倍增 LCT
LINK:树 考虑暴力 保存每个版本的父亲 然后暴力向上跳.得分20. 考虑离线 可以离线那么就可以先把树给搞出来 然后考虑求k级祖先 可以倍增求. 如何判断合法 其实要求路径上的边的时间戳<= ...
- 6.18 省选模拟赛 字符串 LCT SAM
LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 18/9/21模拟赛-Updated
18/9/21模拟赛 期望得分:100:实际得分:0 qwq 拿到题目第一眼,我去,这不是洛谷原题(仓鼠找Sugar)吗 又多看了几眼,嗯,对,除了是有多组数据外,就是原题 然后码码码....自以为 ...
- @省选模拟赛03/16 - T3@ 超级树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...
- 3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...
- 【FJOI 20170305】省选模拟赛
题面被改成了个猪... T1猪猪划船(boat) [题目描述] 6只可爱的猪猪们一起旅游,其中有3只大猪A,B,C,他们的孩子为3只小猪a,b,c.由于猪猪们十分凶残,如果小猪在没有父母监护的情况下, ...
- 洛谷[LnOI2019]长脖子鹿省选模拟赛 简要题解
传送门 听说比赛的时候T4T4T4标程锅了??? WTF换我时间我要写T3啊 于是在T4T4T4调半天无果的情况下260pts260pts260pts收场真的是tcltcltcl. T1 快速多项式变 ...
- 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)
一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...
随机推荐
- angular入门--列表排序
首先,先上代码 <html ng-app="app1"> <head> <meta charset='utf-8' /> <meta na ...
- 初用MySQL Mysql示例库 Navicat15
初用MySQL Mysql示例库 Navicat15 查询MySQl版本 Mysql shell > select version(); 右括号,not version 查看初始密码 M ...
- Kafka消费者拉取数据异常Unexpected error code 2 while fetching data
Kafka消费程序间歇性报同一个错: 上网没查到相关资料,只好自己分析.通过进一步分析日志发现,只有在拉取某一个特定的topic的数据时报错,如果拉取其他topic的数据则不会报错.而从这个异常信息来 ...
- sql-exists、not exists的用法
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:select name from student where sex = 'm' and mark exists(select 1 ...
- 05 Vue项目搭建
Vue-CLI 项目搭建 1.环境搭建 安装node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ 安装cnpm npm install -g cnpm --regi ...
- 纯js实现日期选取功能
平年: 2月-->28天 4,6,9,11月-->30天 1,3,5,7,8,10,12月-->31天 闰年: 2月-->29天 4,6,9,11月-->30天 1,3, ...
- java 面向对象(七):类结构 方法(四)递归方法
1.定义:递归方法:一个方法体内调用它自身.2.如何理解递归方法?> 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制.> 递归一定要向已知方向递归,否则这种 ...
- python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程
python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 目录 python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 ...
- YAPI工具配置LDAP统一用户认证
背景:因为搭建了LDAP,因此希望将所有配置库或工具都使用LDAP进行统一用户认证,YAPI是其中一个. YAPI:使用docker-compose进行了安装,具体安装步骤自行百度. LDAP:使用d ...
- REACT——虚拟DOM
深入了解虚拟DOM 实际顺序 jsx->createElemnt ->虚拟DOM(JS 对象)->真实DOM 虚拟DOM中的Diff算法 :当react查找差异的时候,就会采用dif ...