Master of Phi HDU - 6265 (推公式)

版权声明:如有错误,请指出,不胜感激。 https://blog.csdn.net/qq_36424540/article/details/83029124

推公式:

1. 把 \varphi (n)  再往下拆一级,拆到\mu(d) 一级, 复杂度 O(2^{20}*20) ,但是得用 dfs 实现,要是二进制枚举会重算很多数字

2. 直接 积性函数的 性质, 直接把\varphi (d) 拆掉,最后把所有的相乘

 

第一种

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=b-1;i>=a;--i)

LL val[30],num[30];
LL sub[30];
LL val_num[30],inv_val[30];

const LL mod=998244353;

LL pow_mod(LL base,LL n)
{
    LL ans=1;
    while(n) {
        if(n&1)  ans=ans*base%mod;
        base=base*base%mod;
        n>>=1;
    }
    return ans;
}

LL ans;
int m;
void dfs(int pos,int cnt,LL tmp,LL t)
{
    if(pos>=m) {
        tmp=tmp*t%mod;
        if(cnt&1) {
            ans=(ans-tmp+mod);
            if(ans>=mod)ans-=mod;
        } else {
            ans=(ans+tmp);
            if(ans>=mod)ans-=mod;
        }
        return;
    }
    dfs(pos+1,cnt+1,tmp*num[pos]%mod,t*inv_val[pos]%mod);
    dfs(pos+1,cnt,tmp*(num[pos]+1)%mod,t);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&m);
        rep(i,0,m) {
            scanf("%lld %lld",&val[i],&num[i]);
        }
        ans=0;
        LL up=1<<m;
        LL n=1;
        rep(i,0,m) {
            val_num[i]=pow_mod(val[i],num[i]);
            inv_val[i]=pow_mod(val[i],mod-2);
            n=n*val_num[i]%mod;
        }
        dfs(0,0,1,n);//pos,tmp,t,
        printf("%lld\n",ans);
    }
    return 0;
}

 

阅读更多
换一批

没有更多推荐了,返回首页