题目

【NOIP2017提高A组模拟9.5】心灵治愈
好吧,我表示比赛时完全看不懂题目

题目解释

【NOIP2017提高A组模拟9.5】心灵治愈
良心的出题人为一道两三句可以讲清楚的题目,又写了一大坨恶心的解释。

容斥

其实题目就是有个数组a[1n+1],已知a[n+1]=m,1<=a[1n]<=m,求a数组的每个数的最大公因数为1的方案数。
正难则反,
用a树数组的可能总数为m^n,减去最大公因数不为1的总数。
直接求出m的质数,容斥一下就可以了。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=100005;
using namespace std;
long long p[N],n,m,ans;
long long mi(long long x,long long y)
{
	long long 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,long long val,long long t)
{
	if(x>p[0])
	{
		ans=(ans+mi(m/val,n)*t+mo)%mo;
		return;
	}
	dg(x+1,val,t);
	dg(x+1,val*p[x],-t);
}
int main()
{
	scanf("%lld%lld",&n,&m);
	long long qm=sqrt(m),m1=m;
	for(long long i=2;i<=qm;i++)
		if(m1%i==0)
		{
			p[++p[0]]=i;
			while(m1%i==0) m1/=i;
		}
	if(m1>1) p[++p[0]]=m1;
	dg(1,1ll,1);
	printf("%lld",ans);
}

相关文章:

  • 2021-06-07
  • 2021-06-21
  • 2021-06-12
  • 2022-01-31
  • 2021-05-16
  • 2021-12-08
  • 2021-06-18
  • 2021-06-18
猜你喜欢
  • 2021-04-26
  • 2021-06-06
  • 2021-10-28
  • 2021-08-24
  • 2021-08-12
  • 2021-06-28
  • 2021-10-06
相关资源
相似解决方案