# 洛谷 P3768 简单的数学题

https://www.luogu.org/problemnew/show/P3768

（也就是说$id^3=id^2\varphi*id^2$，好神奇啊）

 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  阅读(285)  评论(0编辑  收藏  举报