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<jthenAi≥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<jthenAi≥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 minimumA1, 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;
}