dtoj2118. GCD Arrays
我似乎粘贴不了题目,一粘贴就卡住。。
Sol.
考虑第一个式子
考虑一个数的因数最多sqrt个,我们暴力枚举n/d的约数g
那么每次要把一个数的倍数的所有位置加一个值。
这个复杂度过不了,我们设
那么每次只需要单点加b了
查询的时候,我们考虑一段n/x相同的x,这些b[x]会贡献n/x次。
整数分块即可。
效率O(nsqrt(n)log(n))

#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #define maxn 400005 using namespace std; int T,n,q,op,mu[maxn],pri[maxn],tot,flag[maxn]; int nn,d,x; vector<int>fac[maxn]; long long tree[maxn],v; void jia(int k,long long val){ for(int i=k;i<=n;i+=i&-i)tree[i]+=val; } long long ask(int k){ long long sum=0; for(int i=k;i;i-=i&-i)sum+=tree[i]; return sum; } int main() { n=400000; mu[1]=1; for(int i=2;i<=n;i++){ if(!flag[i])mu[i]=-1,pri[++tot]=i; for(int j=1;j<=tot&&i*pri[j]<=n;j++){ flag[i*pri[j]]=1; if(i%pri[j]==0)break; mu[i*pri[j]]=-mu[i]; } } for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i)fac[j].push_back(i); while(1){ T++; scanf("%d%d",&n,&q); if(!n&&!q)break; printf("Case #%d:\n",T); memset(tree,0,sizeof tree); while(q--){ scanf("%d",&op); if(op==1){ scanf("%d%d%lld",&nn,&d,&v); if(nn%d!=0)continue; int tmp=nn/d;int sz=fac[tmp].size(); for(int i=0;i<sz;i++){ jia(fac[tmp][i]*d,mu[fac[tmp][i]]*v); } } else { scanf("%d",&x); int now=1,la=1; long long ans=0; while(now<=x){ la=x/(x/now); ans+=(ask(la)-ask(now-1))*1LL*(x/now); now=la+1; } printf("%lld\n",ans); } } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构