1. 程式人生 > 實用技巧 >T147403 「TOC Round 4」吃,都可以吃

T147403 「TOC Round 4」吃,都可以吃

若不考慮 \(m\) 的限制,打表可以發現:

  • \(p=2^n\left(n>1\right)\) 時,最大的 \(f_i\)\(5\),有十個 \(i\)\(f_i\)\(5\),它們可以通過 \(p\) 算出來。

  • \(p=3\times 2^n\left(n>0\right)\) 時,最大的 \(f_i\)\(5\),有一個 \(i\)\(f_i\)\(5\),它可以通過 \(p\) 算出來。

  • \(p=2\) 時,最大的 \(f_i\)\(f_6=f_7=f_8=f_{14}=f_{15}=f_{22}=f_{23}=f_{24}=f_{30}=f_{31}=6\)

  • \(p=3\) 時,最大的 \(f_i\)\(f_{15}=6\)

  • \(p=5\) 時,最大的 \(f_i\)\(f_{79}=5\)

剩下最大的 \(f_i\leq 4\),而 \(4\) 的分佈是很密集的。

所以討論完上面的情況,然後用暴力跑即可。

具體證明我也不會,可以問 \(\text A\color{red}{\text{utumnKite}}\) 神仙,我就暫時咕咕咕了。

code:

#include<bits/stdc++.h>
using namespace std;
#define Db double
#define Min(x,y)((x)<(y)?x:y)
#define For(i,x,y)for(i=x;i<=(y);i++)
#define int long long
const int num[10]={3,4,7,11,12,15,20,28,60,92};
int f[100005],p,n,m;
void work()
{
	int mx=0,j,i;
	For(i,1,100000)
	{
		f[i]=6;
		For(j,1,signed(sqrt(Db(i))))
		if(j!=p)f[i]=Min(f[i],f[i-j*j]+1);
	}
	For(i,1,Min(100000,n))
	if(f[i]>mx)mx=f[i];
	cout<<mx<<endl;
	For(i,1,n)
	if(f[i]==mx)
	{
		if(!m--)break;
		cout<<i<<' ';
		if(i==15&&p==3||i==31&&p==2||i==79&&p==5)break;
	}
}
bool pd(bool type)
{
	int x=p;
	if(!type)
	{
		if(x%4)return 0;
		x>>=2;
	}
	else
	{
		if(x%6)return 0;
		x/=6;
	}
	while(x>1)
	if(x&1)return 0;
	else x>>=1;
	return 1;
}
signed main()
{
	int i;
	cin>>n>>p>>m;
	if(pd(0))
	{
		For(i,0,9)
		if(num[i]*p*(p>>1)>0&&num[i]*p*(p>>1)<=n)
		{
			if(!i)cout<<"5\n";
			if(m--)cout<<num[i]*p*(p>>1)<<' ';
			else exit(0);
		}
		else break;
		if(!i)work();
	}
	else if(pd(1)&&14*(p/3)*(p/3)<=n)
	{
		cout<<"5\n";
		if(m--)cout<<14*(p/3)*(p/3)<<' ';
	}
	else work();
	while(m>0)cout<<"-1 ",m--;
	return 0;
}