zoukankan      html  css  js  c++  java
  • 【莫比乌斯反演】BZOJ2154 Crash的数字表格

    Description

      求sigma lcm(x,y),x<=n,y<=m。n,m<=1e7。

    Solution

      lcm没有什么直接做的好方法,用lcm=x*y/gcd转成gcd来做

      就是要求sigma d*f(x/d,y/d)

      f(x,y)为x和y以内gcd正好为1的对数

      F为所有对数,于是有F(x,y)=x*(x+1)/2*y*(y+1)/2

      f(x,y)=sigma (1<=i<=x) i*i*mu(i)*F(x/i,y/i) 

      f用莫比乌斯反演解决,这两个式子都套上分块优化到sqrt,于是总复杂度sqrt*sqrt=n

      分块优化具体可以见上一篇blog

    Code

      一开始全开LL MLE了一发

      然后又WA了两发,第一次是有一地方算的时候溢出

      一开始为了避免MLE把prime数组/50,但其实只能/20的样子

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=1e7+5,mod=20101009;
     7 
     8 bool flag[maxn];
     9 int prime[maxn],mu[maxn],cnt;
    10 int sum[maxn],s[maxn];
    11 int n,m;
    12 
    13 void getmu(){
    14     mu[1]=1;
    15     for(int i=2;i<=n;i++){
    16         if(!flag[i]){
    17             mu[i]=-1;
    18             prime[++cnt]=i;
    19         }
    20         for(int j=1;i*prime[j]<=n&&j<=cnt;j++){
    21             flag[i*prime[j]]=1;
    22             if(i%prime[j]==0){
    23                 mu[i*prime[j]]=0;
    24                 break;
    25             }
    26             mu[i*prime[j]]=-mu[i];
    27         }
    28     }
    29     for(int i=1;i<=n;i++)
    30         sum[i]=(sum[i-1]+(ll)i*i*mu[i]%mod)%mod;
    31 }
    32 
    33 ll F(int x,int y){
    34     return (ll)((ll)x*(x+1)/2%mod)*((ll)y*(y+1)/2%mod)%mod;
    35 }
    36 
    37 ll f(int x,int y){
    38     ll ret=0;
    39     int p;
    40     for(int i=1;i<=x;i=p+1){
    41         p=min(x/(x/i),y/(y/i));
    42         ret=(ret+(ll)(sum[p]-sum[i-1])*F(x/i,y/i))%mod;
    43     }
    44     return ret;
    45 }
    46 
    47 int main(){
    48     scanf("%d%d",&n,&m);
    49     if(n>m) swap(n,m);
    50     for(int i=1;i<=n;i++) s[i]=(s[i-1]+i)%mod;
    51     getmu();
    52     
    53     int pos;
    54     ll ans=0;
    55     for(int i=1;i<=n;i=pos+1){
    56         pos=min(n/(n/i),m/(m/i));
    57         ans=(ans+(ll)(s[pos]-s[i-1])*f(n/i,m/i))%mod;
    58     }
    59     printf("%lld
    ",(ans+mod)%mod);
    60     return 0;
    61 }
  • 相关阅读:
    475. Heaters
    69. Sqrt(x)
    83. Remove Duplicates from Sorted List Java solutions
    206. Reverse Linked List java solutions
    100. Same Tree Java Solutions
    1. Two Sum Java Solutions
    9. Palindrome Number Java Solutions
    112. Path Sum Java Solutin
    190. Reverse Bits Java Solutin
    202. Happy Number Java Solutin
  • 原文地址:https://www.cnblogs.com/xkui/p/4597275.html
Copyright © 2011-2022 走看看