光速幂学习笔记
光速幂
黑科技……
使用情况
快速求 的值。
在幂运算的底数和取余的模数已经确定的情况下可以使用光速幂。
比如 P3747 [六省联考 2017] 相逢是问候 中需要用光速幂,否则很难卡过。
原理
根据拓展欧拉定理:
对于 ,有
可以先把 的值缩小到 。
令 ,对于 显然有
就可以将 转化为:
写法
所以就能 地预处理:
定义两个数组
令 ,显然可以通过 得到数组 ,其中要初始化数组为 。
令 ,显然可以通过 得到数组 ,其中初始化数组为 。
所以 。
代码
#include <bits/stdc++.h>
using namespace std;
#define L(i,j,k) for(int (i)=(j);i<=(k);(i)++)
const int p=998244352,N=4e4;
int n,x,a[N]={1},b[N]={1},bl;
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>x>>n;bl=sqrt(x)+1;
L(i,1,bl) a[i]=1ll*a[i-1]*x%p;
L(i,1,bl) b[i]=1ll*b[i-1]*a[bl]%p;
L(i,1,n) cin>>x,cout<<1ll*a[x%bl]*b[x/bl]%p<<' ';
}
UPD:2022.10.6
终于回来更新使用 的做法了。
国庆期间一道多校模拟。
Dahsa. 常数之神 小W
出题人声称光速幂要卡常才能过,且其复杂度与幂数的值域挂钩。
你这光速幂太假了
结果只要用拓展欧拉定理先降幂再进行预处理,就能吊打标算。
同时,标算的快速幂做法依赖于数据随机。
在数据随机的情况下,理论上只需进行 次快速幂,所以 的时间复杂度可以通过。
但只要把数据改成反向递增的过程,就能轻松卡掉这一做法。
如果使用上面提到的使用 先降幂后预处理的光速幂做法,可以将时间复杂度优化到 的预处理和 的询问的程度,能在不用任何包括 O2 在内的优化跑赢魔鬼卡常的标算。
这题中,由于模数已知,所以可以直接提前计算出其 值和对应光速幂数组的预处理长度,算是一个常数优化。
而且,这种做法不依赖数据随机,时间复杂度能做到严格 ,只有 的询问常数,也不用像题解的光速幂那样分成三块,虽然预处理的时间复杂度降低了,但那样只会让询问的时间增长,但实际上光速幂的预处理常数可以忽略不计,所以此时只分成两块是更优的。
#include <bits/stdc++.h>
using namespace std;
#define L(i,j,k) for(int (i)=(j);i<=(k);(i)++)
#define R(i,j,k) for(int (i)=(j);i>=(k);(i)--)
#define FST ios::sync_with_stdio(0);cin.tie(0);
unsigned long long seed;
inline unsigned long long next_integer(){
seed^=seed<<19;seed^=seed>>31;
seed^=seed<<13;return seed;
}const int mod=2005232425;
int n,k;unsigned long long V,a[134217728],mi,lst;
long long x[90000]={1},y[90000]={1},bl=52440,ans,phi=1375016400;
void build(){
L(i,1,bl) x[i]=x[i-1]*k%mod;
L(i,1,bl) y[i]=y[i-1]*x[bl]%mod;
}void out(unsigned long long b){
if(b>=phi) b%=phi,b+=phi;
ans+=(lst=x[b%bl]*y[b/bl]%mod);
}int main(){
freopen("w.in","r",stdin);freopen("w.out","w",stdout);
FST cin>>n>>V>>k>>seed;
L(i,0,n-1) a[i]=next_integer()&V;build();
L(i,0,n-1) swap(a[i],a[next_integer()&n-1]);
mi=a[n-1];out(mi);
R(i,n-2,0)
if(a[i]<mi) out(mi=a[i]);
else ans+=lst;
cout<<ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)