把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【洛谷4226】避难所(构造)

点此看题面

  • 定义一个正整数\(n\)\(b\)进制下各位数上乘积为\(F(n,b)\)
  • 用一个贪心的方法求最小的\(n\)满足\(F(n,b)=p\):从\(b-1\)\(2\)试除,直至\(p=1\)
  • 给定进制\(b\),要求举一个反例,或判断不存在。
  • 数据组数\(\le200\)\(b\le10^5\)

\(b\)足够大时:构造

其实题目中给出的样例已经给了我们很明显的提示。。。

假设存在两个质数\(p,q\),我们想要构造最优解\(pq,pq,pq\),并让它的贪心解法得到\(p,p,p,q^3\)。那么就需要满足:

\[pq<q^3<b<p^2\Rightarrow\begin{cases}p>\sqrt b,\\\sqrt p<q<\sqrt[3]b\end{cases} \]

那么我们只要让\(p\)取大于\(\sqrt b\)的最小质数,\(q\)取大于\(\sqrt p\)的最小质数。

\(b\)足够大的时候,肯定能够满足\(q<\sqrt[3]b\)

\(b\)比较小时:暴力

既然\(b\)比较小,我们直接暴力枚举\(1<i\le j\le k<b\),用题目中给出的贪心方法计算\(F(i\times j\times k,b)\)是否会被分出超过\(3\)项即可。

P.S. 后来看题解了解到此时\(b\)最大为\(5^3=125\)

代码:\(O(Tn)\)

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
using namespace std;
int n,Pt,P[N+5];
namespace FastIO
{
	#define FS 100000
	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('\n');}
}using namespace FastIO;
I int Greedy(RI x) {RI t=0;for(RI i=n-1;i^1;--i) W(!(x%i)) x/=i,++t;return t;}//贪心
I void BF() {for(RI i=n-1;i;--i) for(RI j=n-1;j>=i;--j) for(RI k=n-1;k>=j;--k)//暴力枚举i,j,k
	if(Greedy(i*j*k)>3) return (void)printf("3 %d %d %d\n",i,j,k);puts("-1");}//验证贪心是否会把它分出超过3项
int main()
{
	RI i,j;for(i=2;i<=N;++i) for(!P[i]&&(P[++Pt]=i),j=1;j<=Pt&&i*P[j]<=N;++j) if(P[i*P[j]]=1,!(i%P[j])) break;//线性筛
	#define G(x) (upper_bound(P+1,P+Pt+1,x)-P)//找到大于x的最小质数
	RI Tt;scanf("%d",&Tt);W(Tt--) scanf("%d",&n),i=G(sqrt(n)),j=G(sqrt(P[i])),//求出p,q
		1LL*P[j]*P[j]*P[j]<n?printf("3 %lld %lld %lld\n",1LL*P[i]*P[j],1LL*P[i]*P[j],1LL*P[i]*P[j]):(BF(),0);return 0;//检验p^3是否小于n
}
posted @ 2021-05-21 15:49  TheLostWeak  阅读(90)  评论(0编辑  收藏  举报