算是一道很毒瘤的题目 考试的时候码+调了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的更多相关文章

  1. 6.18 省选模拟赛 树 倍增 LCT

    LINK:树 考虑暴力 保存每个版本的父亲 然后暴力向上跳.得分20. 考虑离线 可以离线那么就可以先把树给搞出来 然后考虑求k级祖先 可以倍增求. 如何判断合法 其实要求路径上的边的时间戳<= ...

  2. 6.18 省选模拟赛 字符串 LCT SAM

    LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...

  3. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  4. 18/9/21模拟赛-Updated

    18/9/21模拟赛 期望得分:100:实际得分:0  qwq 拿到题目第一眼,我去,这不是洛谷原题(仓鼠找Sugar)吗 又多看了几眼,嗯,对,除了是有多组数据外,就是原题 然后码码码....自以为 ...

  5. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  6. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  7. 【FJOI 20170305】省选模拟赛

    题面被改成了个猪... T1猪猪划船(boat) [题目描述] 6只可爱的猪猪们一起旅游,其中有3只大猪A,B,C,他们的孩子为3只小猪a,b,c.由于猪猪们十分凶残,如果小猪在没有父母监护的情况下, ...

  8. 洛谷[LnOI2019]长脖子鹿省选模拟赛 简要题解

    传送门 听说比赛的时候T4T4T4标程锅了??? WTF换我时间我要写T3啊 于是在T4T4T4调半天无果的情况下260pts260pts260pts收场真的是tcltcltcl. T1 快速多项式变 ...

  9. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

随机推荐

  1. html鼠标自定义右键菜单:css+js实现自定义html右键菜单

    我们在网页中很多都有右键菜单的功能,一般点击右键显示的是浏览器默认的菜单选项,那么我们直接如何通过css+js实现html的右键菜单呢?这篇文章将讲解html鼠标自定义右键菜单的实现原理和实现代码. ...

  2. 洛谷 P3592 [POI2015]MYJ

    题意 给定\(m\)个区间\([a_i,b_i]\)以及\(c_i\),对于一个含有\(n\)个元素的序列\(ans[]\),区间\(i\)对其的贡献为\(\min\{ans_i\}(i\in[a_i ...

  3. 005.Nginx配置下载站点

    一 下载站点 1.1 下载站点配置 语法:autoindex on | off; 默认值:autoindex off; 配置段:http,server,location Nginx默认不允许列出整个目 ...

  4. pytest框架使用教程

    Pytest框架 一.简介 pytest:基于unittest之上的单元测试框架 有什么特点? 自动发现测试模块和测试方法 断言更加方便,assert + 表达式,例如 assert 1 == 1 灵 ...

  5. include文件包含漏洞

    发现allow_url_include 是on状态 既然已经直接包含了phpinfo()是文件,首先搜索了一下allow_url_include,发现是处于打开的状态. 既然 allow_url_in ...

  6. 【Nginx】实现负载均衡、限流、缓存、黑白名单和灰度发布,这是最全的一篇了!

    写在前面 在<[高并发]面试官问我如何使用Nginx实现限流,我如此回答轻松拿到了Offer!>一文中,我们主要介绍了如何使用Nginx进行限流,以避免系统被大流量压垮.除此之外,Ngin ...

  7. Maven [ERROR] 不再支持源选项 5,请使用 7 或更高版本的解决办法

    刚刚学Maven,当我点击test时 就出现了这两个错误: [ERROR] 不再支持源选项 5.请使用 7 或更高版本.[ERROR] 不再支持目标选项 5.请使用 7 或更高版本. 后来在看到这篇文 ...

  8. 数据可视化基础专题(九):Matplotlib 基础(一)坐标相关

    1.前言 图表要素如下图所示 # sphinx_gallery_thumbnail_number = 3 import matplotlib.pyplot as plt import numpy as ...

  9. 数据可视化之DAX篇(十)在PowerBI中累计求和的两种方式

    https://zhuanlan.zhihu.com/p/64418286 假设有一组数据, 已知每一个产品贡献的利润,如果要计算前几名产品的贡献利润总和,或者每一个产品和利润更高产品的累计贡献占总体 ...

  10. 文件上传漏洞fuzz字典生成脚本小工具分享

    前言 学习xss的时候翻阅资料发现了一个文件上传漏洞fuzz字典生成脚本小工具,试了试还不错,分享一下 配置 需要python2环境 工具地址:https://github.com/c0ny1/upl ...