chen_03 Orz!
题意
给定长度为 n 的数组 a,Q 次询问 lcm(al,al+1,…,ar−1,ar),对 109+7 取模。
题解
对于每个右端点,我们维护每个左端点的答案。
具体的,设当前右端点为 m,我们尝试找到数列 bi 使得区间 [i,m] 的答案为 ∏mj=ibj,显然 bi|ai。
假设我们已求出右端点为 m−1 时的数组 b,现在尝试求出右端点为 m 时的数组 b′。
首先,b′m=am。若 j>i 时 b′j 都已求出,那么有:
m∏j=i+1b′j=am∏m−1j=i+1bjgcd(am,∏m−1j=i+1bj)
m∏j=ib′j=am∏m−1j=ibjgcd(am,∏m−1j=ibj)
两式相除得:
b′i=bigcd(am,∏m−1j=ibj)gcd(am,∏m−1j=i+1bj)
设 X=am,Y=bi,Z=∏m−1j=i+1bj,则:
gcd(am,∏m−1j=ibj)gcd(am,∏m−1j=i+1bj)=gcd(X,YZ)gcd(X,Z)
=gcd(Xgcd(X,Z),YZgcd(X,Z))=gcd(Xgcd(X,Z),Y)=gcd⎛⎜⎝amgcd(am,∏m−1j=i+1bj),bi⎞⎟⎠
通过上述式子我们已经可以 O(Tn2loga) 求出答案。
设 si=∏m−1j=ibj,注意到 gcd(am,∏m−1j=i+1bj)=gcd(am,si+1) 一定是 am 的约数,且对 ∀1≤i<j≤m,有 gcd(am,sj)|gcd(am,si),因此不同的 gcd(am,si) 取值只有 O(loga) 种。
如何快速找到这 O(loga) 个位置来减少计算 gcd 的次数呢?注意到若 gcd(am,si)>gcd(am,si+1),那么一定存在某个质因子 p 在左式中的次数比右式中的高。
设 p 在 am,si,si+1 中的出现次数分别为 x,y,z,那么 y>z,又因为 min(x,y)>min(x,z),因此 x>z。
故 min(x,y)>z,所以这等价于 (si+1modam)modgcd(am,si)≠0。
因此,用一个变量 tmp 存当前 gcd(am,si) 的值,根据 (si+1modam)modtmp 是否等于 0 可判断出是否需要更新 tmp。
总时间复杂度 O(Tn(n+log2a))。
Code
#include<bits/stdc++.h>
#define LL long long
#define mod 1000000007
using namespace std;
int n,q,Test_num;
LL tmp,c,tmp1,tmp2;
LL a[302],b[302],s[302];
LL ans[302][302];
inline LL gcd(LL a,LL b)
{
return b? gcd(b,a%b):a;
}
inline void solve()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
for(int i=1;i<=n;++i)
{
ans[i][i]=(b[i]=a[i])%mod,s[i]=1;
for(int j=i-1;j;--j)s[j]=((__int128)s[j+1]*b[j])%a[i];
tmp2=gcd(s[1],a[i]);
for(int j=1;j<i;++j)if(s[j+1]%tmp2)tmp1=gcd(s[j+1],a[i]),c=tmp2/tmp1,tmp2=tmp1,tmp/=c,b[j]/=c;
for(int j=i-1;j;--j)ans[j][i]=(ans[j+1][i]*(b[j]%mod))%mod;
}
for(int i=1,x,y;i<=q;++i)scanf("%d%d",&x,&y),printf("%lld\n",ans[x][y]);
}
int main()
{
for(scanf("%d",&Test_num);Test_num--;)solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!