亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java怎么解決歐拉函數和莫比烏斯反演問題

發布時間:2022-04-06 16:43:11 來源:億速云 閱讀:148 作者:iii 欄目:編程語言

本文小編為大家詳細介紹“java怎么解決歐拉函數和莫比烏斯反演問題”,內容詳細,步驟清晰,細節處理妥當,希望這篇“java怎么解決歐拉函數和莫比烏斯反演問題”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

題意:給定a,b,c,d,k

            x屬于[1 , c],y屬于[1 , d],求滿足gcd(x,y)=k的對數。其中<x,y>和<y,x>算相同。

解法一:不妨設c<d,x<=y。問題可以轉化為x屬于[1,c / k ],y屬于[1,d/k ],x和y互質的對數。

            那么假如y<=c/k,那么對數就是y從1到c/k歐拉函數的和。如果y>c/k,就只能從[ c/k+1 , d ]枚舉,然后利用容斥。詳見代碼:

/*********************************************************
  file name: hdu1695.cpp
  author : kereo
  create time:  2015年02月11日 星期三 18時08分43秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int primecnt,factcnt;
int prime[MAXN],euler[MAXN],factor[N][2];
void getprime(){
    primecnt=0;
    memset(prime,0,sizeof(prime));
    for(int i=2;i<MAXN;i++){
        if(!prime[i])
            prime[primecnt++]=i;
        for(int j=0;j<primecnt && prime[j]<=MAXN/i;j++){
            prime[prime[j]*i]=1;
            if(i%prime[j] == 0)
                break;
        }
    }
}
void geteuler(){
    memset(euler,0,sizeof(euler));
    euler[1]=1;
    for(int i=2;i<MAXN;i++){
        if(!euler[i]){
            for(int j=i;j<MAXN;j+=i){
                if(!euler[j])
                    euler[j]=j;
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
}
int getfactor(int x){
    factcnt=0;
    for(int i=0;prime[i]<=x/prime[i];i++){
        factor[factcnt][1]=0;
        if(x%prime[i] == 0){
            factor[factcnt][0]=prime[i];
            while(x%prime[i] == 0){
                x/=prime[i];
                factor[factcnt][1]++;
            }
            factcnt++;
        }
    }
    if(x!=1){
        factor[factcnt][0]=x;
        factor[factcnt++][1]++;
    }
    return factcnt;
}
int solve(int n,int m){
    int ans=0;
    getfactor(m);
    for(int i=1;i<(1<<factcnt);i++){
        int cnt=0,res=1;
        for(int j=0;j<factcnt;j++){
            if(i&(1<<j)){
                cnt++;
                res*=factor[j][0];
            }
        }
        if(cnt & 1)
            ans+=n/res;
        else 
            ans-=n/res;
    }
    return n-ans;
}
int main(){
    int T,kase=0;
    scanf("%d",&T);
    getprime();
    geteuler();
    while(T--){
        printf("Case %d: ",++kase);
        int a,b,c,d,k;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        if(k == 0 || k>b || k>d){
            printf("0\n");
            continue;
        }
        if(b>d)
            swap(b,d);
        b/=k; d/=k;
        ll ans=0;
        for(int i=1;i<=b;i++)
            ans+=euler[i];
        for(int i=b+1;i<=d;i++)
            ans+=solve(b,i);
        printf("%I64d\n",ans);
    }
	return 0;
}

解法二:莫比烏斯反演。

其中"設F(a,b,k)表示有多少組x≤a,y≤b,且Gcd(a,b)≥k"的"Gcd(a,b)>=k"應該是k | Gcd(x,y)。

java怎么解決歐拉函數和莫比烏斯反演問題

/*********************************************************
  file name: hdu1695.cpp
  author : kereo
  create time:  2015年02月12日 星期四 09時08分41秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int primecnt;
int vis[MAXN],mu[MAXN],prime[MAXN],sum[MAXN];
void Mobius(){
    primecnt=0;
    memset(vis,0,sizeof(vis));
    mu[1]=1;
    for(int i=2;i<MAXN;i++){
        if(!vis[i]){
            prime[primecnt++]=i;
            mu[i]=-1;
        }
        for(int j=0;j<primecnt && i*prime[j]<MAXN;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]) 
                mu[i*prime[j]]=-mu[i];
            else{
                mu[i*prime[j]]=0;
                break;
            }
        }
    }
}
ll solve(int l,int r){
    ll ans=0;
    if(l>r)
        swap(l,r);
    int last;
    for(int i=1;i<=l;i=last+1){
        last=min(l/(l/i),r/(r/i));
        ans+=(ll)(sum[last]-sum[i-1])*(ll)(l/i)*(ll)(r/i);
    }
    return ans;
}
int main(){
    int T,kase=0;
    Mobius();
    sum[0]=0;
    for(int i=1;i<MAXN;i++)
        sum[i]=sum[i-1]+mu[i];
    scanf("%d",&T);
    while(T--){
        int a,b,c,d,k;
        printf("Case %d: ",++kase);
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        if(k == 0 || k>b || k>d){
            printf("0\n");
            continue;
        }
        if(b>d)
            swap(b,d);
        b/=k; d/=k;
        printf("%I64d\n",solve(b,d)-solve(b,b)/2);
    }
	return 0;
}

讀到這里,這篇“java怎么解決歐拉函數和莫比烏斯反演問題”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節
推薦閱讀:
  1. 歐拉函數
  2. DFS序,歐拉序

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

双桥区| 承德县| 莎车县| 绥棱县| 五大连池市| 龙南县| 邯郸县| 赫章县| 阿城市| 萨嘎县| 葫芦岛市| 元江| 辽源市| 大埔县| 南江县| 太谷县| 濉溪县| 分宜县| 富宁县| 泾川县| 韩城市| 永宁县| 海林市| 高邮市| 阜宁县| 镇宁| 钦州市| 斗六市| 西乌| 子长县| 永丰县| 万荣县| 宝鸡市| 潍坊市| 慈溪市| 宜川县| 山东省| 个旧市| 江西省| 都匀市| 景东|