[SNOI2019]数论
https://www.luogu.org/problemnew/show/P5330
题解
我们要求有多少个x满足:
\[x=a_i+P*k_1=b_j+Q*k_2
\]
然后移一下:
\[a_i+P*k_1=b_j \ (mod\ Q)
\]
可以发现这个东西是有循环节的。
可以发现它的循环周期是\(lcm(P,Q)\)。
那么我们需要求的是对于每个\(a_i\),它在长度为\(Q\)的环上走,能碰到几个\(B\)。
直接算就可以了。
代码
#include<bits/stdc++.h>
#define N 1000009
using namespace std;
typedef long long ll;
ll q,p,n,m,t,a[N],b[N],sum[N],rk[N],ans,be[N],num[N];
bool vis[N];
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
inline ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
inline ll lcm(ll x,ll y){return x/gcd(x,y)*y;}
int main(){
p=rd();q=rd();n=rd();m=rd();t=rd();t--;
for(int i=1;i<=n;++i)a[i]=rd();
for(int i=1;i<=m;++i)b[rd()]=1;
for(int i=0;i<q;++i)if(!vis[i]){
int xx=i;
int cnt=0,last=-1;
while(1){
vis[xx]=1;
rk[xx]=++cnt;be[xx]=i;
if(last>=0)sum[xx]+=sum[last];
sum[xx]+=b[xx];
last=xx;
xx=(xx+p)%q;
if(vis[xx])break;
}
num[i]=sum[last];
}
ll len=lcm(q,p);
for(int i=1;i<=n;++i)if(a[i]<=t){
ll le=t-a[i],id=a[i]%q;
ans+=(le/len)*num[be[id]];le%=len;le/=p;
ll yy=(id+le*p)%q;
if(rk[yy]>=rk[id])ans+=sum[yy]-sum[id]+b[id];
else ans+=num[be[id]]-sum[id]+b[id]+sum[yy];
}
cout<<ans;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· 程序员转型AI:行业分析
· 为DeepSeek添加本地知识库
· 深入集成:使用 DeepSeek SDK for .NET 实现自然语言处理功能
· .NET程序员AI开发基座:Microsoft.Extensions.AI