• BZOJ2005 莫比乌斯反演


    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=2005

    实际上把这些被挡住的点的坐标和能量值列举出来可以发现有个公式:

    “对于坐标系第一象限任意的整点(即横纵坐标均为整数的点)p(n,m),

    其与原点o(0,0)的连线上除过原点整点的个数为gcd(n,m)。

    其他象限上个数则为gcd(abs(n),abs(m))”

    答案就是sum(2*gcd(x,y)-1)  [x=(1..n),y=(1..m)]

    //证明:http://www.cnblogs.com/huhuuu/archive/2011/11/25/2263803.html

    公式进一步化简:

    对于本题,gcd(x,y)的值一定不会超过max(n,m)。这样直接枚举gcd(x,y)所有可能的值,再套用hdu 1695给出来的那个G函数就行啦~

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cmath>
     4 using namespace std;
     5 #define LL long long
     6 #define MMX 100010
     7 int mu[MMX],msum[MMX];
     8 LL n,m;
     9 bool check[MMX];
    10 int prime[MMX];
    11 
    12 void Moblus()
    13 {
    14     memset(check,false,sizeof(check));
    15     mu[1] = 1;
    16     int tot = 0;
    17     for(int i = 2; i <= MMX; i++)
    18     {
    19         if( !check[i] )
    20         {
    21             prime[tot++] = i;
    22             mu[i] = -1;
    23         }
    24         for(int j = 0; j < tot; j++)
    25         {
    26             if(i * prime[j] > MMX) break;
    27             check[i * prime[j]] = true;
    28             if( i % prime[j] == 0)
    29             {
    30                 mu[i * prime[j]] = 0;
    31                 break;
    32             }
    33             else
    34             {
    35                 mu[i * prime[j]] = -mu[i];
    36             }
    37         }
    38     }
    39     msum[1]=mu[1];
    40     for (int i=2;i<=MMX;i++)
    41         msum[i]=msum[i-1]+mu[i];
    42 }
    43 
    44 
    45 LL G(int n,int m)           //加分块优化
    46 {
    47     LL ans = 0;
    48     if(n > m)   swap(n,m);
    49     for(int i = 1, la = 0; i <= n; i = la+1)
    50     {
    51         la = min(n/(n/i),m/(m/i));
    52         ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i);      //事先预处理:msum[n]=SUM(mu[1..n])
    53     }
    54     return ans;
    55 }
    56 
    57 int main()
    58 {
    59     Moblus();
    60     cin>>n>>m;
    61     LL sum=0;
    62     for (LL i=1;i<=max(m,n);i++)
    63         sum+=i*G(m/i,n/i);
    64     sum=2*sum-n*m;
    65     cout<<sum<<endl;
    66 }
    View Code
  • 相关阅读:
    0diff算法参考资料
    js 对象属性值
    一些带有设计模式的优秀代码
    vue 配置多页面
    cms 管理系统
    网络技术:EtherChannel 链路汇聚
    网络技术:VLAN 中继协议(VTP)
    网络管理:管理信息库
    网络管理:抽象语法表示 ASN.1
    网络管理:基本编码规则(BER)
  • 原文地址:https://www.cnblogs.com/pdev/p/4101485.html
Copyright © 2020-2023  润新知