Given three integers
n(1≤n≤1018)
,
m(1≤m≤105)
,
k(1≤k≤1018)
. you should find a list of integer
A1,A2,…,Am
which satisfies three conditions:
1. A1+A2+⋯+Am=n .
2. 1≤Ai≤k−1 for each (1≤i≤m) .
3. GCD(A1,A2,…,Am)=1 .GCD means the greatest common divisor
4. if i<j then Ai≥Aj .
1. A1+A2+⋯+Am=n .
2. 1≤Ai≤k−1 for each (1≤i≤m) .
3. GCD(A1,A2,…,Am)=1 .GCD means the greatest common divisor
4. if i<j then Ai≥Aj .
As the author is too lazy to write a special judge, if there's no answer ouput "I love ACM", And if there's more than one answer, output the one has the minimum A1 , and if there still multiple answer make the A2 as small as possible, then A3,A4…
主要思想:
把n先均分成m份,多余的分摊到前面。如果数列存在两个相差1的数,那么这个数列整体的GCD为1.
这里有好多特殊情况要处理,比如m=1,m=2,n=m等等等。
比如
10 2 10
10 10 3
10 5 3
2 1 2
1 1 3
ps:TJU的数据很弱,队友丢了情况都过了......
自己有一处判断加上去之后就WA,不知道为什么。
#include<cstdio>
#include<cstring>
#define imp {printf("I love ACM\n"); return;}
using namespace std;
long long ans[100005];
long long gcd(long a,long b)
{
long long r;
while(b>0)
{
r=a%b;
a=b;
b=r;
}
return a;
}
void work(long long n,long long m,long long k)
{
int i,j;
long long x,y;
// if((m*k-m)<=n)
//实在搞不懂为什么加上上面那句话就会WA
if(n<m) imp
if(n==m)
{
if(k<2) imp
else
{
printf("1");
for(i=2;i<=m;i++) printf(" 1");
printf("\n");
return ;
}
}
if(m==1)
{
if(n!=1) imp
if(k<=1) imp
printf("%lld\n",n);
}
else if(m==2)
{
if((n&1)==0)
{
x=y=n/2;
x++;
y--;
while(gcd(x,y)!=1 && x<k && y>0)
{
x++;
y--;
}
if(gcd(x,y)!=1) imp
if(x>=k) imp
printf("%lld %lld\n",x,y);
}
else
{
x=y=n/2;
x++;
if(gcd(x,y)!=1) imp
if(x>=k) imp
printf("%lld %lld\n",x,y);
}
}
else
{
for(i=1;i<=m;i++) ans[i]=n/m;
if(n%m==0)
{
ans[1]++;
ans[m]--;
if(ans[1]>=k) imp
for(i=1;i<m;i++) printf("%lld ",ans[i]);
printf("%lld\n",ans[m]);
}
else
{
n-=ans[1]*m;
i=0;
while(n--) ans[++i]++;
if(ans[1]>=k) imp
for(i=1;i<m;i++) printf("%lld ",ans[i]);
printf("%lld\n",ans[m]);
}
}
}
int main()
{
long long n,m,k;
while(~scanf("%lld%lld%lld",&n,&m,&k))
work(n,m,k);
return 0;
}