洛谷 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 }

 

posted @ 2018-07-28 11:16  hehe_54321  阅读(286)  评论(0编辑  收藏  举报
AmazingCounters.com