P8103
Part 1
判断可行性
我们先把所有数除以他们的最大公约数,考虑到答案一定是一个数翻倍得到的,所以此时如果所有数的和是
Part 2
构造方案
考虑到如果所有数的和大于
Part 3
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,i,t,k,a[100001],b,c,d,m,l[1000001],r[1000001];
int main()
{
scanf("%lld",&t);
for(k=1;k<=t;k=k+1)
{
scanf("%lld",&n);b=0;c=0;d=0;
for(i=1;i<=n;i=i+1)
{
scanf("%lld",&a[i]);
b=__gcd(b,a[i]);
}
for(i=1;i<=n;i=i+1)a[i]=a[i]/b;
for(i=1;i<=n;i=i+1)c=c+a[i];
for(i=1;;i=i*2)
{
if(i>c){d=1;break;}
if(i==c)break;
}
if(d==1){printf("NO\n");continue;}
else
{
printf("YES\n");m=0;
while(1)
{
b=0;c=0;d=0;
for(i=1;i<=n;i=i+1)
{
if(a[i]%2==1)
{
c=c+1;
if(c==2)
{
m=m+1;c=0;
if(a[i]>a[d]){l[m]=i;r[m]=d;a[i]=a[i]-a[d];a[d]=a[d]*2;}
else {l[m]=d;r[m]=i;a[d]=a[d]-a[i];a[i]=a[i]*2;}
}
else d=i;
}
}
if(c==1)break;
for(i=1;i<=n;i=i+1)b=__gcd(b,a[i]);
for(i=1;i<=n;i=i+1)a[i]=a[i]/b;
}
printf("%lld\n",m);
for(i=1;i<=m;i=i+1)printf("%lld %lld\n",l[i],r[i]);
}
}
return 0;
}