• SPOJ-7001 VLATTICE 莫比乌斯反演定理


      题目链接:http://www.spoj.com/problems/VLATTICE/

      题意:求gcd(x,y,z)=1,1<=x,y,z<=n,的个数。

      开始做的时候枚举gcd(x,y),然后求z与gcd(x,y)互素的个数个数,O(n*sqrt(n))赌赌RP,然后TLE了。。。

      后来才知道要用到莫比乌斯反演定理:  

        已知 f(n) = sigma(d|n, g(d))

        那么 g(n) = sigma(d|n, mu(d)*f(n/d))

      还有另一种形式更常用:

        在某一范围内,已知 f(n) = sigma(n|d, g(d))

        那么 g(n) = sigma(n|d, mu(d/n)*f(d))

      这个题目用到了第二种形式,设g(n)为gcd(x,y,z)=n的个数,f(n)为n | g(i*n)的个数,那么有f(n)=sigma(n|d,g(d)),那么g(n)=sigma(n|d, mu(d/n)*f(d)),我们要求g(1),则g(1)=sigma(n|d, mu(d)*f(d)),其中mu(n)是莫比乌斯函数:

                

      上面的公式忘打括号了,(-1)^k...

      因为f(d)=(n/d)*(n/d)*(n/d),所以g(1)=sigma( mu(d)*(n/d)*(n/d)*(n/d) ).

      然后用线性筛法在O(n)的时间内求出mu(n)就可以了。。

     1 //STATUS:C++_AC_3.22S_14MB
     2 #include <functional>
     3 #include <algorithm>
     4 #include <iostream>
     5 //#include <ext/rope>
     6 #include <fstream>
     7 #include <sstream>
     8 #include <iomanip>
     9 #include <numeric>
    10 #include <cstring>
    11 #include <cassert>
    12 #include <cstdio>
    13 #include <string>
    14 #include <vector>
    15 #include <bitset>
    16 #include <queue>
    17 #include <stack>
    18 #include <cmath>
    19 #include <ctime>
    20 #include <list>
    21 #include <set>
    22 #include <map>
    23 using namespace std;
    24 //#pragma comment(linker,"/STACK:102400000,102400000")
    25 //using namespace __gnu_cxx;
    26 //define
    27 #define pii pair<int,int>
    28 #define mem(a,b) memset(a,b,sizeof(a))
    29 #define lson l,mid,rt<<1
    30 #define rson mid+1,r,rt<<1|1
    31 #define PI acos(-1.0)
    32 //typedef
    33 typedef long long LL;
    34 typedef unsigned long long ULL;
    35 //const
    36 const int N=1000010;
    37 const int INF=0x3f3f3f3f;
    38 const int MOD=100000,STA=8000010;
    39 const LL LNF=1LL<<60;
    40 const double EPS=1e-8;
    41 const double OO=1e15;
    42 const int dx[4]={-1,0,1,0};
    43 const int dy[4]={0,1,0,-1};
    44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    45 //Daily Use ...
    46 inline int sign(double x){return (x>EPS)-(x<-EPS);}
    47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
    48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
    49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
    50 template<class T> inline T Min(T a,T b){return a<b?a:b;}
    51 template<class T> inline T Max(T a,T b){return a>b?a:b;}
    52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
    53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
    54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
    55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
    56 //End
    57 int isprime[N],mu[N],prime[N];
    58 int cnt;
    59 void Mobius(int n)
    60 {
    61     int i,j;
    62     //Init phi[N],prime[N],全局变量初始为0
    63     cnt=0;mu[1]=1;
    64     for(i=2;i<=n;i++){
    65         if(!isprime[i]){
    66             prime[cnt++]=i;  //prime[i]=1;为素数表
    67             mu[i]=-1;
    68         }
    69         for(j=0;j<cnt && i*prime[j]<=n;j++){
    70             isprime[i*prime[j]]=1;
    71             if(i%prime[j])
    72                 mu[i*prime[j]]=-mu[i];
    73             else {mu[i*prime[j]]=0;break;}
    74         }
    75     }
    76 }
    77 
    78 int T,n;
    79 
    80 int main(){
    81  //   freopen("in.txt","r",stdin);
    82     int i,j,t;
    83     LL ans;
    84     Mobius(1000000);
    85     scanf("%d",&T);
    86     while(T--)
    87     {
    88         scanf("%d",&n);
    89         ans=3;
    90         for(i=1;i<=n;i++)ans+=(LL)mu[i]*(n/i)*(n/i)*((n/i)+3);
    91         printf("%lld
    ",ans);
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    visual basic VB.NET实例系列教程第三节(常用循环结构之乘法表与数列)
    visual basic VB.NET实例系列教程第二节(好玩又有趣的龟兔赛跑程序)
    visual basic VB.NET实例系列教程第一节(简单实用抽奖程序)
    对DevSecOps的一点认识
    轻便的一句话反弹shell语句
    ActiveMQ 反序列化漏洞(CVE-2015-5254)复现
    《信息安全风险管理》梗概
    微信服务商分账功能开发(PHP)
    哈夫曼编码—文件的压缩与解压(Java)
    哈夫曼编码—数据压缩与解压(Java)
  • 原文地址:https://www.cnblogs.com/zhsl/p/3269123.html
Copyright © 2020-2023  润新知