其他分享
首页 > 其他分享> > F. K-th Power 容斥,莫比乌斯

F. K-th Power 容斥,莫比乌斯

作者:互联网

F. K-th Power

传送门

牛客:https://ac.nowcoder.com/acm/contest/34866/F

cf:https://codeforces.com/group/5zHJ4CTyoU/contest/392060/problem/F

题意:求区间[l,r]中,不含有\(p^k\)因子的数字的个数。其中p是质数。

可以用容斥+莫比乌斯解决。

问题转换成求[1,r]和[1,l-1]含有\(p^k\)因子的数字的个数,然后相减。

对于求[l,r]中含有\(p^k\)因子数字的个数,设含有\(i^k\)因子的数字的个数为\(f(i)\)

则:\(ans=f(2)+f(3)+f(5)+...-f(2*3)-f(3*5)-f(2*5)...+f(2*3*5)...\)

所以对每个数统计出能由多少个不重复质数乘得,判断奇偶决定符号。如果由重复质数因子,则不是上式成员。

#include <bits/stdc++.h>
//#define ll long long
#define ll long long
const ll N = 1e7+10;
ll q_pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=a*res;
        a=a*a;
        b>>=1;
    }
    return res;
}
ll q_sqrt(ll x,ll k){
    ll l=0,r=1e9;
    while(l<r){
        ll m=(l+r+1)>>1;
        if(q_pow(m,k)<=x){
            l=m;
        }
        else r=m-1;
    }
    return l;
}
int pr[N];
bool ck[N];
std::vector<int>ve;
void init(){
    for(int i=2;i<1e4;i++){
        ll k=i*i;
        for(ll j=k;j<N;j+=k)ck[j]=1;
    }
    for(ll i=2;i<N;i++){
        if(!pr[i]){
            ve.push_back(i);
            for(ll j=i;j<N;j+=i)pr[j]++;
        }
    }
}
ll get(ll p,ll k){
    if(k>60||p<2)return 0;
    ll m=q_sqrt(p,k);
    ll ans=0;
    for(int i=2;i<N&&q_pow(i,k)<=p;i++){   
        if(ck[i])continue;
        if(pr[i]&1)ans+=(p/q_pow(i,k));
        else ans-=(p/q_pow(i,k));   
    }    
    return ans;    
}
signed main(){
    //std::ios::sync_with_stdio(false);
    init();
    ll l,r,k;
    std::cin>>l>>r>>k;
    std::cout<<r-l+1-(get(r,k)-get(l-1,k))<<"\n";
}

标签:Power,res,ll,容斥,long,个数,因子,th,质数
来源: https://www.cnblogs.com/wtn135687/p/16529646.html