码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu】P2303Longge的问题(莫比乌斯反演)

时间:2018-01-25 23:08:11      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:等等   输出   cst   prim   ==   git   str   its   algo   

  就让我这样的蒟蒻发一个简单易想的题解吧!!!


  这题我一开始一看,woc这不是莫比乌斯反演么,推推推,推到杜教筛,输出结果一看不对


  emmm回来仔细想想……woc推错了?


  然后撕烤半天打了个暴力,A了


  首先我们学过莫比乌斯反演的一般能够想到枚举gcd,记为w


  所以我们需要求的就是$\sum\limits_{w|n}w\sum\limits_{w|i}[gcd(i,n)=w]$

  然后……就到了激动人心的构造函数环节……

  设$F(w)=\sum\limits_{w|i}[w|gcd(i,n)]$

  $f(w)=\sum\limits_{w|i}[w=gcd(i,n)]$

  于是有$F(w)=\sum\limits_{w|d}f(d)$

  于是……$f(w)=\sum\limits_{w|d}\mu(\frac{d}{w})F(d)$

  容易(个屁,我手玩了半年)发现,当$d|n$时$F(d)=\frac{n}{d}$,其他情况下$F(d)=0$

  然后问题就变成了$\sum\limits_{w|n}w\sum\limits_{w|d}\mu(\frac{d}{w})F(d)$

  设$t=\frac{d}{w}$

  原式化为$\sum\limits_{w|n}w\sum\limits_{t|d}\mu(t)F(tw)$

  然后我们发现了什么?

  没错w可以暴力枚举qwq!没错t可以暴力枚举qwq!

  因为我们枚举到根n就可以枚举出n的所有因子!  t同理!

  来吧让我们暴……等等$\mu$怎么算?

  废话啊按着莫比乌斯函数的定义暴力qwq!

  

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<iostream>
#include<cmath>
#define maxn 5000020
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==-)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-0;
        ch=getchar();
    }
    return num*f;
}

bool vis[maxn];
int prime[maxn],tot;
int mu[maxn];

inline int calcmu(long long n){
    if(n<maxn)    return mu[n];
    long long sqt=sqrt(n);
    long long now=n;int ans=0;
    for(int j=1;j<=tot;++j){
        int i=prime[j];
        if(i>sqt)    break;
        if(now%i)    continue;
        int cnt=0;
        while((now%i)==0){
            cnt++;    now/=i;
            if(cnt>1)    return 0;
        }
        ans++;
    }
    if(now>0)    ans++;
    if(ans&1)    return -1;
    else         return 1;
}
        

int main(){
    mu[1]=vis[1]=1;
    for(int i=2;i<maxn;++i){
        if(vis[i]==0){
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=tot&&prime[j]*i<maxn;++j){
            vis[i*prime[j]]=1;
            if(i%prime[j])    mu[i*prime[j]]=-mu[i];
            else            break;
        }
    }
    long long n=read(),ans=0;
    int sqt=sqrt(n);
    for(int i=1;i<=sqt;++i){
        if(n%i)    continue;
        long long d=n/i;long long now=0;
        long long sar=sqrt(d);
        for(int j=1;j<=sar;++j){
            if(d%j)    continue;
            now+=calcmu(j)*(n/(j*i));
            if(j*j==d)    continue;
            now+=calcmu(d/j)*(n/((d/j)*i));
        }
        ans+=now*i;
        
        if(1LL*i*i==n)    continue;
        long long ret=n/i;
        d=n/ret;now=0;
        sar=sqrt(d);
        for(int j=1;j<=sar;++j){
            if(d%j)    continue;
            now+=calcmu(j)*(n/(j*ret));
            if(j*j==d)    continue;
            now+=calcmu(d/j)*(n/((d/j)*ret));
        }
        ans+=now*ret;
    }
    printf("%lld\n",ans);
    return 0;
}

 

【Luogu】P2303Longge的问题(莫比乌斯反演)

标签:等等   输出   cst   prim   ==   git   str   its   algo   

原文地址:https://www.cnblogs.com/cellular-automaton/p/8353385.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!