• 51nod1237 最大公约数之和 V3


    n<=1e10,问1<=i<=n,1<=j<=n,gcd(i,j)的和%1e9+7。

    QAQ自推的第一道,虽然很简单而且走了很多弯路而且推错了一次被ccz大爷调教,但还是挺感动的。。

    其实在推数论之前可以先打个$mu$和$varphi $的表,推个两三步就验证一下,否则如果是大数论题,推错的后果是极其严重的。

    $sum_{i=1}^{n}sum_{j=1}^{n}(i,j)$

    $=sum_{d=1}^{n}sum_{i=1}^{n}sum_{j=1}^{n}[(i,j)=d]$

    严重错误!d不见了。上面这个式子最后等于1.

    $sum_{i=1}^{n}sum_{j=1}^{n}(i,j)$

    $=sum_{d=1}^{n}dsum_{i=1}^{n}sum_{j=1}^{n}[(i,j)=d]$

    闪一句:反演!

    $=sum_{d=1}^{n}dsum_{d|t,tleqslant n}mu(frac{t}{d})(left lfloor frac{n}{t} ight floor)^2$

    闪一句:这里尝试$t=kd$,结果失败了。正确操作是把t放前面……

    $=sum_{t=1}^{n}(left lfloor frac{n}{t} ight floor)^2sum_{d|t}dmu(frac{t}{d})$

    $=sum_{t=1}^{n}(left lfloor frac{n}{t} ight floor)^2varphi(t)$

    漂亮!把欧拉函数丢去杜教筛即可。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 //#include<assert.h>
     6 #include<algorithm> 
     7 //#include<iostream>
     8 //#include<bitset>
     9 using namespace std;
    10 
    11 #define LL long long
    12 LL n,m;
    13 const int mod=1e9+7;
    14 #define maxn 5000011
    15 int phi[maxn],sumphi[maxn],prime[maxn],lp; bool notprime[maxn];
    16 void pre(int n)
    17 {
    18     phi[1]=1; sumphi[1]=1;
    19     for (int i=2;i<=n;i++)
    20     {
    21         if (!notprime[i]) prime[++lp]=i,phi[i]=i-1;
    22         sumphi[i]=sumphi[i-1]+phi[i];
    23         sumphi[i]-=sumphi[i]>=mod?mod:0;
    24         for (int j=1,tmp;j<=lp && 1ll*prime[j]*i<=n;j++)
    25         {
    26             notprime[tmp=prime[j]*i]=1;
    27             if (i%prime[j]) phi[tmp]=phi[i]*(prime[j]-1);
    28             else {phi[tmp]=phi[i]*prime[j]; break;}
    29         }
    30     }
    31 }
    32 
    33 struct Edge{LL to;int v,next;};
    34 #define maxh 1000007
    35 struct Hash
    36 {
    37     int first[maxh],le; Edge edge[maxn];
    38     Hash() {le=2;}
    39     void insert(LL y,int v) {int x=y%maxh; Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
    40     int find(LL y) {int x=y%maxh; for (int i=first[x];i;i=edge[i].next) if (edge[i].to==y) return edge[i].v; return -1;}
    41 }h;
    42 
    43 int calc(LL n)
    44 {
    45     if (n<=m) return sumphi[n];
    46     int tmp=h.find(n); if (tmp!=-1) return tmp;
    47     LL ans=1ll*n%mod*((n+1)%mod)%mod*((mod+1)>>1)%mod;
    48     for (LL i=2,last;i<=n;i=last+1)
    49     {
    50         last=n/(n/i);
    51         ans-=((last-i+1)%mod)*1ll*calc(n/i)%mod;
    52         ans+=ans<0?mod:0;
    53     }
    54     h.insert(n,ans);
    55     return ans;
    56 }
    57 
    58 int main()
    59 {
    60     scanf("%lld",&n);
    61     m=pow(n,2.0/3); pre(m);
    62     LL ans=0;
    63     for (LL i=1,last;i<=n;i=last+1)
    64     {
    65         last=n/(n/i);
    66         ans+=(calc(last)-calc(i-1))*1ll*((n/i)%mod)%mod*((n/i)%mod)%mod;
    67         ans+=ans<0?mod:0,ans-=ans>=mod?mod:0;
    68     }
    69     printf("%lld
    ",ans);
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    [LeetCode] 1640. Check Array Formation Through Concatenation
    [LeetCode] 754. Reach a Number
    [LeetCode] 1457. Pseudo-Palindromic Paths in a Binary Tree
    [LeetCode] 1352. Product of the Last K Numbers
    [LeetCode] 261. Graph Valid Tree
    [LeetCode] 323. Number of Connected Components in an Undirected Graph
    [LeetCode] 1605. Find Valid Matrix Given Row and Column Sums
    [LeetCode] 1253. Reconstruct a 2-Row Binary Matrix
    [LeetCode] 455. Assign Cookies
    [LeetCode] 1358. Number of Substrings Containing All Three Characters
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8319021.html
Copyright © 2020-2023  润新知