[hdu5608]function
题意:∑d|nf(d)=n2−3n+2,求\sum_{i=1}^{n}f(i)\mod 10^{9}+7 , n \leqslant 10^{9} \left( T \leqslant 500\right)组数据,只有5组>10^{6}
题解:看了式子感觉像是反演,但是呢....
令S(n)=\sum_{i=1}^{n}f(i)
那么S(n)=\sum_{i=1}^{n}\sum_{d|i}f(d)=\sum_{i=1}^{n}f(d)\lfloor\frac{n}{d}\rfloor=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor} f(d)=\sum_{d=1}^{n}S(\lfloor\frac{n}{d}\rfloor)=\sum_{i=1}^{n}(i-1)*(i-2)
所以S(n)=\frac{n*(n-1)*(n-2)}{3}-\sum_{i=2}^{n}f(i)
所以老套路,预处理maxn^{\frac{2}{3}}的S(i),这个可以直接算,总复杂度也是O(n^{\frac{2}{3}})
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #define MAXN 5000000 #define mod 1000000007 #define inv 333333336 #define ll long long using namespace std; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int f[MAXN+5]; map<int,ll> mp; ll calc(int x) { if(x<=MAXN)return f[x]; map<int,ll>::iterator it; if((it=mp.find(x))!=mp.end())return it->second; ll sum=1LL*x*(x-1)%mod*(x-2)%mod*inv%mod; int last; for(int i=2;i<=x;i=last+1) { last=x/(x/i); sum-=1LL*(last-i+1)*calc(x/i); while(sum<0)sum+=mod; } return (mp[x]=sum); } int main() { for(int i=1;i<=MAXN;i++) f[i]=1LL*(i-2)*(i-1)%mod; for(int i=1;i<=MAXN;i++) for(int j=i<<1;j<=MAXN;j+=i) f[j]=(f[j]-f[i]+mod)%mod; // for(int i=1;i<=10;i++)cout<<f[i]<<endl; for(int i=2;i<=MAXN;i++) f[i]=(f[i]+f[i-1])%mod; for(int t=read();t;t--) printf("%lld\n",calc(read())); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步