觉得论文里的图有点问题 不过思路很棒
注意到,如果任意的三个向量都可以与某两个向量等价,那么便可以从n(n>2)个向量中任选三个向量出来,用与它们等价的两个向量代替它们,从而变成n-1个向量。不断重复上述的过程,直到只剩下两个向量为止,这时剩下的两个向量便是一个可行解。而由问题描述可以知道:对于任意三个向量都存在两个向量与它们等价。这便意味这种方法是可行的。
BZOJ上没有SPJ 没过 但原题过了
传送门:http://main.edu.pl/en/archive/oi/12/sko
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
inline void exgcd(int a,int b,int &x,int &y){
if (b==0){ x=1; y=0; return; }
exgcd(b,a%b,x,y);
int tem=y; y=x-a/b*y; x=tem;
}
inline void solve(int a1,int b1,int a2,int b2,int &x,int &y,int &y2){
if (!a1) { x=a2; y=b2; y2=b1; }
if (!a2) { x=a1; y=b1; y2=b2; }
int p,q,d;
exgcd(a1,a2,p,q); d=p*a1+q*a2;
x=d; y=p*b1+q*b2;
y2=abs(a1*b2-a2*b1)/d;
}
int n,a[105],b[105];
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",a+i,b+i);
int x,y,y2,tem;
solve(a[1],b[1],a[2],b[2],x,y,y2);
for (int i=3;i<=n;i++){
tem=y2;
solve(a[i],b[i],x,y,x,y,y2);
y2=__gcd(y2,tem);
}
printf("%d %d\n%d %d\n",x,y,0,y2);
return 0;
}