【CF900D】異常なシーケンス

タイトル

深刻な精神的衰退

うん、明らかに反転

最初に満たしている必要があります\(X- | Y-の\を)そう答えは、\(\ 0)

私たちは、列の数を列挙\(GCDの\)された\(dは\)または\(dは\)倍数を

だから、答えは、

\ [\ sum_ {X | D} [D | Y] \ミュー(\ FRAC {X} {D})、G(\ FRAC {Y}、{D})\]

\(G(D)\)に示すととして\(D \)整数n列の数、明らか下板プラグ、すると\(G(D)= \ sum_ {I = 1} ^ D \ binom {D -1} {I-1} = 2 ^ {D-1} \)

コード

#include<bits/stdc++.h>
#define re register
#define LL long long
inline int read() {
    char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=1e9+7;
const int maxn=1e5+5;
inline int ksm(int a,int b) {
    int S=1;
    for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) S=1ll*S*a%mod;
    return S;
}
int n,m,T,ans;
int f[maxn],p[maxn>>1],mu[maxn];
inline int getmu(int x) {
    if(x<=T) return mu[x];int now=0;
    for(re int i=1;i<=p[0]&&x!=1;++i) {
        if(x%p[i]) continue;
        x/=p[i];now^=1;
        if(x%p[i]==0) return 0;
    }
    if(x!=1) now^=1;
    if(!now) return 1;return -1;
}
inline void add(int i) {
    if(i%n) return;
    int x=getmu(i/n);
    if(x==1) ans=(ans+ksm(2,m/i-1))%mod;
    if(x==-1) ans=(ans-ksm(2,m/i-1)+mod)%mod;
}
int main() {
    scanf("%d%d",&n,&m);
    if(m%n) {puts("0");return 0;}
    T=std::ceil(std::sqrt(m/n));f[1]=mu[1]=1;
    for(re int i=2;i<=T;i++) {
        if(!f[i]) p[++p[0]]=i,mu[i]=-1;
        for(re int j=1;j<=p[0]&&p[j]*i<=T;++j) {
            f[p[j]*i]=1;if(i%p[j]==0) break;
            mu[p[j]*i]=-1*mu[i];
        }
    }
    for(re int i=1;i*i<=m;++i) {
        if(m%i) continue;
        add(i);if(m/i!=i) add(m/i);
    }
    printf("%d\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/asuldb/p/11373482.html