1. 程式人生 > 實用技巧 >jzoj 5348. 【NOIP2017提高A組模擬9.5】心靈治癒

jzoj 5348. 【NOIP2017提高A組模擬9.5】心靈治癒

Description

Input

Output

Solution


Explanation

題目真把我看吐了,又臭又長的題面完全沒有閱讀的慾望好吧
其實就是有\(n+1\)個數,已知第n+1個數是m,然後第1~n個數∈[1,m],求這些數互質的方案數
正難則反
容易得出總方案是\(m^{n}\)
我們再減去重複的就好了
將m分解質因數,再用容斥減就好了

Code

#include <cstdio>
#include <algorithm>
#include <cmath>
#define MO 1000000007
#define ll long long
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int tot,i,prime[30000];
ll n,m,t,ans;
ll ksm(ll x,ll y)
{
    ll sum=1;x%=MO;
    while (y)
    {
        if (y&1) sum=(sum*x)%MO;
        x=(x*x)%MO;
        y>>=1;
    }
    return sum;
}
void dg(int x,ll y,int z)
{
    if (x>tot)
    {
        ans=(ans+ksm(m/y,n)*(z%2==0?1:-1)+MO)%MO;
        return;
    }
    dg(x+1,y*prime[x],z+1);
    dg(x+1,y,z);
}
int main()
{
    open("heal");
    scanf("%lld%lld",&n,&m);
    t=m;
    for (i=2;i<=floor(sqrt(m));i++)
    {
        if (t%i==0)
        {
            prime[++tot]=i;
            while (t%i==0) t/=i;
        }
    }
    if (t>1) prime[++tot]=t;
    dg(1,1,0);
    printf("%lld",ans);
    return 0;
}