记录编号 |
364907 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[河南省队2016]幂 |
最终得分 |
100 |
用户昵称 |
FoolMike |
是否通过 |
通过 |
代码语言 |
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;
}