莫比乌斯反演1001 BZOJ 2818 莫比乌斯反演例题

来源:互联网 发布:java工程师考试 编辑:程序博客网 时间:2024/05/21 18:33

题意:
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
思路:
可以欧拉函数解,比较简单,为了练习一下莫比乌斯反演
很多解释都在代码里面了,这道题基本上就是例题…

/**/#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 100005;const int inf=(1<<28)-1;#define maxp 10000005bool notprimes[maxp];int primes[maxp];int mu[maxp];LL Sum[maxp],Pre[maxp];void get_mu(){    memset(notprimes,false,sizeof(notprimes));    primes[0]=0;    mu[1]=1;    for(int i=2;i<maxp;++i)    {        if(!notprimes[i])        {            primes[++primes[0]]=i;            Sum[i]=1;            mu[i]=-1;        }        for(int j=1;j<=primes[0];++j)        {            if((LL)primes[j]*i>=maxp) break;            notprimes[i*primes[j]]=true;            if(i%primes[j])            {                mu[i*primes[j]]=-mu[i];                Sum[i*primes[j]]=mu[i]-Sum[i];                //T=i的时候,Sum[T]=Sum[i]                //当为T再加上一个与之前不重复的素因子成为T1                //Sum[T1]=∑(p|T1,mu[T1/p])=∑(p|T,-mu[T/p]) + mu[T]                //之所以取负数,因为mu[T],对T进行素因子分解以后都是互异素数时                //mu[T]=(-1)^k   k是素数的个数,素数加了一个,所以取反                //再加上多加一个素数后会多一个mu[T]就是Sum[T1]            }            else            {                mu[i*primes[j]]=0;                Sum[i*primes[j]]=mu[i];                //这里分两种情况 T=i T1=i*primes[j]                //1. T=p1 * p2 * p3 * p4 * ... pk                  //此时∑(p|T1,mu[T1/p]),p=primes[j]的时候mu[T]=Sum[T1]=(-1)^k                //2. T=p1^2 * p2 * p3 * p4 * ... pk                //此时不论p是什么,对T1/p就行质因子分解后都不会存在所有素数互异的情况                 break;//代表i不是素数,mu[i*primes[j]]必然是0             }        }    }}int main(){    get_mu();    Pre[0]=0;    for(int i=1;i<maxp;++i)        Pre[i]=Pre[i-1]+Sum[i];    /*for(int i=1;i<=4;++i)        printf("%d ",Sum[i]);printf("\n");*/    int n;    scanf("%d",&n);    LL Ans=0;    int last;    for(int i=1;i<=n;i=last+1)    {        last=n/(n/i);        //这里是莫比乌斯反演的题目里经常用到的分块加速        //因为很多情况下我们都会用到下面这个式子        //但是我们发现有些连续的数(n/i)都是一样的        //我们就可以通过前缀来把它们一起求出来        //假设n==9        //i=1->i=2->i=3->i=4->i=5->i=10        //因为5~9的n/i==1所以直接一起求出来          Ans+=(LL)(n/i)*(n/i)*(Pre[last]-Pre[i-1]);    }    printf("%lld\n",Ans);    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 下雨天了怎么办 新套路 万达兑换券过期怎么办 直播间没一个人怎么办 快手直播人少怎么办 快手直播人气少怎么办 被火山主播踢出房间怎么办 遇到同事的排挤怎么办 交警处理事故不公平怎么办 派出所处理事情不公平怎么办 淘宝号不健康了怎么办 作业盒子忘记密码怎么办 一起作业忘记密码怎么办 手机不能录视频怎么办 网络机顶盒连不上wifi怎么办 obs游戏源黑屏怎么办 微信视频打不开怎么办? xp关闭hdmi声音怎么办 大锅天线无信号怎么办 人喝酒喝醉了怎么办 电信网络电视不清楚怎么办 饭店老板拖欠员工工资怎么办 出国旅游不会英语怎么办 香港转机21小时怎么办 动车坐过站了怎么办 在美国开车超速怎么办? 办出国旅游护照怎么办 中关村三小午饭怎么办 电视不能看直播怎么办 电视系统无信号怎么办 电视视频无信号怎么办 大锅盖没有信号怎么办 锅盖天线没信号怎么办 锅盖天线信号低怎么办 小米盒子没信号怎么办 有线电视没台了怎么办 宝马液晶屏碎了怎么办 电视显示屏坏了怎么办 索尼电视x8000c黑屏怎么办 电视合子不用了怎么办 电视色调为0怎么办 电视机电源线断了怎么办