洛谷 P3768 简单的数学题
https://www.luogu.org/problemnew/show/P3768
化简一下式子,就是$\sum_{d=1}^ncalc(d)d^2\varphi(d)$
其中$calc(d)=\frac{({\lfloor}\frac{n}{d}{\rfloor}+1)^2{{\lfloor}\frac{n}{d}{\rfloor}}^2}{4}$
可以对calc(d)做整除分块,那么要求$d^2\varphi(d)$的前缀和
看一眼数据范围,大概要杜教筛
凑了一会,发现令$f(d)=d^2\varphi(d)$,$g(d)=d^2$,$h=f*g$,那么$h(n)=n^2\sum_{d|n}\varphi(d)=n^3$
(也就是说$id^3=id^2\varphi*id^2$,好神奇啊)
那么就好办了,$n^3$的前缀和是有公式的($1^3+2^3+..+n^3=(1+2+..+n)^2$)
杜教筛那个式子套一下就行了。。也可以预处理一点前缀和
复杂度?...不会算
以下是瞎扯:
设预处理1-K
算一次x,复杂度是$f(x)=\sum_{i=1}^{x/K}\sqrt{\frac{x}{i}}=O(\frac{x}{\sqrt{K}})$
后半部分复杂度是$\sum_{i=1}^{n/K}f(\frac{n}{i})=nK^{-\frac{1}{2}}\sum_{i=1}^{n/K}\frac{1}{i}=nK^{-\frac{1}{2}}log(n/K)$
总复杂度是$nK^{-\frac{1}{2}}log(n/K)+K$
当$K=n^{\frac{2}{3}}$时,复杂度是$n^{\frac{2}{3}}log$
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<map> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 ll md; 15 ll H(ll n) 16 { 17 __int128 t=__int128(n+1)*n/2%md; 18 return t*t%md; 19 } 20 ll G(ll n) 21 { 22 return __int128(n)*(n+1)*(2*n+1)/6%md; 23 } 24 ll Mod(ll n,ll d=md) 25 { 26 if(n>=0) return n%d; 27 else if(n%d==0) return 0; 28 else return d+n%d; 29 } 30 const ll K=5000000; 31 ll HH[K+100],prime[K+100],len; 32 bool nprime[K+100]; 33 map<ll,ll> ma; 34 ll calc(ll n) 35 { 36 if(n<=K) return HH[n]; 37 if(ma.count(n)) return ma[n]; 38 ll i,j,ans=H(n); 39 for(i=2;i<=n;i=j+1) 40 { 41 j=n/(n/i); 42 ans=Mod(ans-Mod(G(j)-G(i-1))*calc(n/i)%md); 43 } 44 return ma[n]=ans; 45 } 46 ll n; 47 ll X(ll d) 48 { 49 __int128 t=__int128(n/d+1)*(n/d)/2%md; 50 return t*t%md; 51 } 52 ll ans; 53 int main() 54 { 55 ll i,j; 56 //md=1000000007; 57 scanf("%lld%lld",&md,&n); 58 HH[1]=1; 59 for(i=2;i<=K;i++) 60 { 61 if(!nprime[i]) {prime[++len]=i;HH[i]=i-1;} 62 for(j=1;j<=len&&i*prime[j]<=K;j++) 63 { 64 nprime[i*prime[j]]=1; 65 if(i%prime[j]==0) 66 { 67 HH[i*prime[j]]=HH[i]*prime[j]; 68 break; 69 } 70 else 71 HH[i*prime[j]]=HH[i]*(prime[j]-1); 72 } 73 } 74 for(i=1;i<=K;i++) HH[i]=HH[i]*i%md*i%md; 75 for(i=1;i<=K;i++) HH[i]=(HH[i-1]+HH[i])%md; 76 // while(1) 77 // { 78 // scanf("%lld",&n); 79 // printf("%lld\n",calc(n)); 80 // } 81 for(i=1;i<=n;i=j+1) 82 { 83 j=n/(n/i); 84 ans=(ans+X(i)*Mod(calc(j)-calc(i-1))%md)%md; 85 } 86 printf("%lld",ans); 87 return 0; 88 }