记录编号 364907 评测结果 AAAAAAAAAA
题目名称 [河南省队2016]幂 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.389 s
提交时间 2017-01-18 16:39:15 内存使用 0.28 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
typedef long long ll;
const int N=110;
set<int> S;
int n,m,len[N];ll ans=1;
int q[N],s,vis[N];
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
ll lcm(ll x,ll y){return x/gcd(x,y)*y;}
ll solve(int p,int sign,ll LCM,ll L,ll R){
	if (!p) return sign*(R/LCM-L/LCM);
	return solve(p-1,sign,LCM,L,R)+solve(p-1,-sign,lcm(LCM,q[p]),L,R);
}
ll solve(ll l,ll r){//分块,可取的整数在[l,r]之间
	static int C=0;C++;s=0;
	for (int i=l;i<=r;i++)
	if (vis[i]!=C){
		q[++s]=i;
		for (int j=i+i;j<=r;j+=i) vis[j]=C;
	}
	return solve(s,-1,1,(l-1)*m,l*m)+m;
}
int main()
{
	freopen("powerz.in","r",stdin);
	freopen("powerz.out","w",stdout);
	scanf("%d%d",&n,&m);
	int Sqrt=sqrt(n);
	len[1]=n-Sqrt;
	for (int i=2;i<=Sqrt;i++)
	if (!S.count(i)){
		int mi=1;
		for (ll j=i*i;j<=n;j*=i,mi++)
		if (!S.count(j)){
			S.insert(j);
			if (j>Sqrt) len[1]--;
		}
		len[mi]++;
	}
	for (int i=1;i<30;i++)
	if (len[i]){
		for (int j=1;j<=i;j++)
			ans+=len[i]*solve(j,i);
	}
	printf("%lld\n",ans);
	return 0;
}