T2找不出来哪里的问题。似乎是容斥系数的锅。
赛场上一直没想出来具体怎么斥,赛后交流用的同学的想法实现。 大致上:
似乎还有个结论是能拼出的话方案唯一。
实现代码:
//g++ b.cpp -o b -g -std=c++14 -O0 -Wall -fsanitize=undefined
#include<cstdio>
#include<algorithm>
#include<cmath>
#define LL long long
#define XL __int128
using namespace std;
namespace rdin{
const int maxr=1e6+10;char buf[maxr],*l,*r;
inline char gtc(){if(l==r){r=(l=buf)+fread(buf,1,maxr,stdin);}return l==r?EOF:*l++;}
inline LL qd(){LL rt=0;char c=gtc();while(c<'0'||c>'9'){c=gtc();}while('0'<=c&&c<='9'){rt=(rt<<3)+(rt<<1)+(c^48),c=gtc();}return rt;}
}
using rdin::qd;
const int maxn=110;const XL maxh=2e18;
int K,lgn,mu[maxn],prime[maxn],ptop=0,vis[maxn];LL N,ans=0;
XL qsm(XL x,int y){XL rt=1;for(;y;y--){rt=min(maxh,rt*x);}return rt;}
LL solve(LL x,LL y){
LL rt=pow<long double>(x,1.0/y);
while(qsm(rt,y)<=x) rt++;
while(qsm(rt,y)>x) rt--;
return rt;
}
int main(){
freopen("in.txt","r",stdin);
N=qd(),K=qd();if(K==1){printf("%lld\n",N);return 0;}
lgn=__lg(N)+1;
for(int i=K;i<=lgn;i++){
static int st[maxn],stop;stop=0;int x=i,flag=0;
for(int j=1;j<=ptop;j++) for(int k=1;x%prime[j]==0;k++){st[++stop]=prime[j],x/=prime[j];if(k>1){flag=1;break;}}
if(flag||(stop&&x>1)) continue;
if(stop) mu[i]=-mu[i/st[1]];
else prime[++ptop]=i,mu[i]=1;
}
for(int i=K;i<=lgn;i++) printf("%d %d\n",mu[i],i);
ans=1;for(int i=K;i<=lgn;i++){
printf("solve %d %lld\n",i,solve(N,i));
ans+=mu[i]*(solve(N,i)-1);
}
printf("%lld\n",ans);
return 0;
}