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

时间:2023-03-09 15:30:55
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\) 的分布是很密集的。到后来就固定了,因为 \(p^2\) 无法对前 \(100\) 产生影响。

所以讨论完上面的情况,然后用暴力跑即可。

具体证明我也不会,可以问 \(\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;
}