求调T2
  • 板块学术版
  • 楼主poly
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/3/5 13:15
  • 上次更新2023/10/23 22:59:43
查看原帖
求调T2
910332
poly楼主2023/3/5 13:15

T2找不出来哪里的问题。似乎是容斥系数的锅。
赛场上一直没想出来具体怎么斥,赛后交流用的同学的想法实现。 大致上:

  • 从K开始筛
  • 不能被拼出来的数为“质数”
  • 只能不封由“质数”拼起来的数,以及能完全被拼出来但含有偶数次“质因子” 的数系数都是0
  • 对于剩下的数为 (1)质因子数+1(-1)^{\text{质因子数}+1}

似乎还有个结论是能拼出的话方案唯一。

实现代码:

//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;
}
2023/3/5 13:15
加载中...