洛谷P3455 笔记
又是一道看了tj的题。
题意
次询问,每次询问给定 ,, ,求 。
, ,
正文
把 扔到上界去,记原式变为
然后利用莫比乌斯函数性质,把等于 的判断去掉,得
接着把 扔到前面去,把整除的条件去掉,记 ,得
最后一步很显然, 放到前面,得到最后的柿子:
这个时候思路很显然了。线性筛筛出 到 内的所有 并做一个前缀和,然后就可以整除分块了。
code
//writer:Oier_szc #include <bits/stdc++.h> #define int long long using namespace std; const int N=1e5+5,INF=2e9,mod=1e9+7; int t,n,a,b,d; int f[N],qzh[N]; int primes[N],st[N],len=0; void xxs() { f[1]=1; for(int i=2;i<=5e4;++i) { if(!st[i]) primes[++len]=i,f[i]=-1; for(int j=1;j<=len&&primes[j]<=5e4/i;++j) { st[i*primes[j]]=true; if(i%primes[j]==0) { f[i*primes[j]]=0; break; } else f[i*primes[j]]=-f[i]; } } for(int i=1;i<=5e4;++i) qzh[i]=qzh[i-1]+f[i]; } signed main() { xxs(); scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld",&a,&b,&d); a/=d,b/=d; n=min(a,b); int ans=0; for(int l=1,r;l<=n;l=r+1) { r=min(a/(a/l),b/(b/l)); ans+=(qzh[r]-qzh[l-1])*(a/l)*(b/l); } printf("%lld\n",ans); } return 0; }
总结一下,可以发现这道题推柿子的技巧在于将难以处理的判断条件用一些转换去掉,得到最终柿子后又用到了线性筛和整除分块的技巧以降低复杂度。
本文作者:StevenZC
本文链接:https://www.cnblogs.com/StevenZC/p/18011419
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步