acm-(辗转相除法、丢番图方程)2020 China Collegiate Programming Contest Qinhuangdao Site I. Interstellar Hunter

题面
传送门
本题其实就是给定若干个整数向量 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) (x_1,y_1),(x_2,y_2),...,(x_n,y_n) (x1,y1),(x2,y2),...,(xn,yn),询问对于整数向量 ( x , y ) (x,y) (x,y)而言是否能够找到一组整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an使得 a 1 ( x 1 , y 1 ) + a 2 ( x 2 , y 2 ) + . . . + a n ( x n , y n ) = ( x , y ) a_1(x_1,y_1)+a_2(x_2,y_2)+...+a_n(x_n,y_n)=(x,y) a1(x1,y1)+a2(x2,y2)+...+an(xn,yn)=(x,y)

首先给出一个结论,任意多个整数向量 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) (x_1,y_1),(x_2,y_2),...,(x_n,y_n) (x1,y1),(x2,y2),...,(xn,yn)的整数线性组合所形成的空间可以被两个整数向量 ( a , b ) , ( 0 , c ) (a,b),(0,c) (a,b),(0,c)通过整数线性组合所表出。

证明:考虑用数学归纳法来证明,
对于一个整数向量 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)而言,一定可以被 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) ( 0 , 0 ) (0,0) (0,0)表出,满足要求;
而对于两个整数向量 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1,y1),(x2,y2)而言,设 d = g c d ( x 1 , x 2 ) d=gcd(x_1,x_2) d=gcd(x1,x2),根据裴蜀定理 ∃ e 1 , e 2 ∈ Z , e 1 x 1 + e 2 x 2 = d \exist e_1,e_2\in Z,e_1x_1+e_2x_2=d e1,e2Z,e1x1+e2x2=d,那么我们有 e 1 ( x 1 , y 1 ) + e 2 ( x 2 , y 2 ) = ( d , e 1 y 1 + e 2 y 2 ) e_1(x_1,y_1)+e_2(x_2,y_2)=(d,e_1y_1+e_2y_2) e1(x1,y1)+e2(x2,y2)=(d,e1y1+e2y2),此外我们还有 x 2 d ( x 1 , y 1 ) − x 1 d ( x 2 , y 2 ) = ( 0 , x 2 d y 1 − x 1 d y 2 ) \frac {x_2}d(x_1,y_1)-\frac{x_1}d(x_2,y_2)=(0,\frac{x_2}dy_1-\frac{x_1}dy_2) dx2(x1,y1)dx1(x2,y2)=(0,dx2y1dx1y2),而 ( d , e 1 y 1 + e 2 y 2 ) (d,e_1y_1+e_2y_2) (d,e1y1+e2y2) ( 0 , x 2 d y 1 − x 1 d y 2 ) (0,\frac{x_2}dy_1-\frac{x_1}dy_2) (0,dx2y1dx1y2)就是与 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1,y1),(x2,y2)等价的一组基。
注意到若 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) ( x 2 , y 2 ) (x_2,y_2) (x2,y2)线性无关,则 x 2 y 1 − x 1 y 2 ≠ 0 x_2y_1-x_1y_2\ne 0 x2y1x1y2=0成立,于是有 ( d , e 1 y 1 + e 2 y 2 ) (d,e_1y_1+e_2y_2) (d,e1y1+e2y2) ( 0 , x 2 d y 1 − x 1 d y 2 ) (0,\frac{x_2}dy_1-\frac{x_1}dy_2) (0,dx2y1dx1y2)是线性无关的。而当 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) ( x 2 , y 2 ) (x_2,y_2) (x2,y2)线性相关时满足 ( 0 , x 2 d y 1 − x 1 d y 2 ) = ( 0 , 0 ) (0,\frac{x_2}dy_1-\frac{x_1}dy_2)=(0,0) (0,dx2y1dx1y2)=(0,0)
我们再看看这组基为何与 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1,y1),(x2,y2)等价,将刚才的两个方程反解一下:
{ e 1 ( x 1 , y 1 ) + e 2 ( x 2 , y 2 ) = ( d , e 1 y 1 + e 2 y 2 ) x 2 d ( x 1 , y 1 ) − x 1 d ( x 2 , y 2 ) = ( 0 , x 2 d y 1 − x 1 d y 2 ) ⇒ { ( x 1 , y 1 ) = x 1 d ( d , e 1 y 1 + e 2 y 2 ) + e 2 ( 0 , x 2 d y 1 − x 1 d y 2 ) ( x 2 , y 2 ) = x 2 d ( d , e 1 y 1 + e 2 y 2 ) − e 1 ( 0 , x 2 d y 1 − x 1 d y 2 ) \begin{cases}e_1(x_1,y_1)+e_2(x_2,y_2)=(d,e_1y_1+e_2y_2)\\\frac {x_2}d(x_1,y_1)-\frac{x_1}d(x_2,y_2)=(0,\frac{x_2}dy_1-\frac{x_1}dy_2) \end{cases}\Rightarrow\begin{cases}(x_1,y_1)=\frac{x_1}d(d,e_1y_1+e_2y_2)+e_2(0,\frac{x_2}dy_1-\frac{x_1}dy_2) \\(x_2,y_2)=\frac{x_2}d(d,e_1y_1+e_2y_2)-e_1(0,\frac{x_2}dy_1-\frac{x_1}dy_2)\end{cases} {e1(x1,y1)+e2(x2,y2)=(d,e1y1+e2y2)dx2(x1,y1)dx1(x2,y2)=(0,dx2y1dx1y2){(x1,y1)=dx1(d,e1y1+e2y2)+e2(0,dx2y1dx1y2)(x2,y2)=dx2(d,e1y1+e2y2)e1(0,dx2y1dx1y2)
反解后不难发现两个向量组可以互相线性表出,也就是两者等价,即 { ( x 1 , y 1 ) , ( x 2 , y 2 ) } \{(x_1,y_1),(x_2,y_2)\} {(x1,y1),(x2,y2)} { ( d , e 1 y 1 + e 2 y 2 ) , ( 0 , x 2 d y 1 − x 1 d y 2 ) } \{(d,e_1y_1+e_2y_2),(0,\frac{x_2}dy_1-\frac{x_1}dy_2)\} {(d,e1y1+e2y2),(0,dx2y1dx1y2)}等价,也可以写成 ∀ x 1 , y 1 , x 2 , y 2 ∈ Z , ∃ a , b , c ∈ Z \forall x_1,y_1,x_2,y_2\in Z,\exist a,b,c\in Z x1,y1,x2,y2Z,a,b,cZ使得 { ( x 1 , y 1 ) , ( x 2 , y 2 ) } \{(x_1,y_1),(x_2,y_2)\} {(x1,y1),(x2,y2)} { ( a , b ) , ( 0 , c ) } \{(a,b),(0,c)\} {(a,b),(0,c)}等价。

最后我们考虑对于向量组 { ( x 1 , y 1 ) , ( x 2 , y 2 ) . . . ( x n , y n ) } \{(x_1,y_1),(x_2,y_2)...(x_n,y_n)\} {(x1,y1),(x2,y2)...(xn,yn)}而言假设其等价于向量组 { ( a , b ) , ( 0 , c ) } \{(a,b),(0,c)\} {(a,b),(0,c)},根据数学归纳法,现在新加入一个向量 ( x n + 1 , y n + 1 ) (x_{n+1},y_{n+1}) (xn+1,yn+1),我们要证明 ∃ a ′ , b ′ , c ′ ∈ Z \exist a',b',c'\in Z a,b,cZ使得新的向量组 { ( x 1 , y 1 ) , . . . , ( x n + 1 , y n + 1 ) } \{(x_1,y_1),...,(x_{n+1},y_{n+1})\} {(x1,y1),...,(xn+1,yn+1)}仍然与两个向量构成的向量组 { ( a ′ , b ′ ) , ( 0 , c ′ ) } \{(a',b'),(0,c')\} {(a,b),(0,c)}所等价。

由于 { ( x 1 , y 1 ) , ( x 2 , y 2 ) . . . ( x n , y n ) } \{(x_1,y_1),(x_2,y_2)...(x_n,y_n)\} {(x1,y1),(x2,y2)...(xn,yn)}等价于 { ( a , b ) , ( 0 , c ) } \{(a,b),(0,c)\} {(a,b),(0,c)},我们不妨看能否将 { ( a , b ) , ( 0 , c ) } \{(a,b),(0,c)\} {(a,b),(0,c)} ( x n + 1 , y n + 1 ) (x_{n+1},y_{n+1}) (xn+1,yn+1)合并成 { ( a ′ , b ′ ) , ( 0 , c ′ ) } \{(a',b'),(0,c')\} {(a,b),(0,c)},首先根据前面的结论我们知道 ∃ a ′ ′ , b ′ ′ , c ′ ′ ∈ Z \exist a'',b'',c''\in Z a,b,cZ使得 { ( a , b ) , ( x n + 1 , y n + 1 ) } \{(a,b),(x_{n+1},y_{n+1})\} {(a,b),(xn+1,yn+1)}等价于 { ( a ′ ′ , b ′ ′ ) , ( 0 , c ′ ′ ) } \{(a'',b''),(0,c'')\} {(a,b),(0,c)},于是 { ( a , b ) , ( 0 , c ) , ( x n + 1 , y n + 1 ) } \{(a,b),(0,c),(x_{n+1},y_{n+1})\} {(a,b),(0,c),(xn+1,yn+1)}等价于 { ( a ′ ′ , b ′ ′ ) , ( 0 , c ′ ′ ) , ( 0 , c ) } \{(a'',b''),(0,c''),(0,c)\} {(a,b),(0,c),(0,c)},注意到 { ( 0 , c ′ ′ ) , ( 0 , c ) } \{(0,c''),(0,c)\} {(0,c),(0,c)}等价于 { ( 0 , g c d ( c , c ′ ′ ) ) } \{(0,gcd(c,c''))\} {(0,gcd(c,c))},也就是说 { ( a ′ ′ , b ′ ′ ) , ( 0 , c ′ ′ ) , ( 0 , c ) } \{(a'',b''),(0,c''),(0,c)\} {(a,b),(0,c),(0,c)}等价于 { ( a ′ ′ , b ′ ′ ) , ( 0 , g c d ( c , c ′ ′ ) ) } \{(a'',b''),(0,gcd(c,c''))\} {(a,b),(0,gcd(c,c))},令 c ′ ′ ′ = g c d ( c , c ′ ′ ) c'''=gcd(c,c'') c=gcd(c,c),因此我们有 ∀ x 1 , y 1 , x 2 , y 2 , . . . , x n + 1 , y n + 1 ∈ Z , ∃ a ′ ′ , b ′ ′ , c ′ ′ ′ ∈ Z \forall x_1,y_1,x_2,y_2,...,x_{n+1},y_{n+1}\in Z,\exist a'',b'',c'''\in Z x1,y1,x2,y2,...,xn+1,yn+1Z,a,b,cZ使得 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n + 1 , y n + 1 ) } \{(x_1,y_1),(x_2,y_2),...,(x_{n+1},y_{n+1})\} {(x1,y1),(x2,y2),...,(xn+1,yn+1)}等价于 { ( a ′ ′ , b ′ ′ ) , ( 0 , c ′ ′ ′ ) } \{(a'',b''),(0,c''')\} {(a,b),(0,c)}

换句话说,对于任何向量组而言,它们都一定等价于某两个向量的构成的向量组,且这两个向量的形式为 ( a , b ) , ( 0 , c ) (a,b),(0,c) (a,b),(0,c)

有了这个结论后,我们考虑维护一个两个基向量 ( a , b ) , ( 0 , c ) (a,b),(0,c) (a,b),(0,c),初始化 a = b = c = 0 a=b=c=0 a=b=c=0,每加入一个向量就考虑将这个新的向量与 ( a , b ) , ( 0 , c ) (a,b),(0,c) (a,b),(0,c)进行合并,得到 ( a ′ , b ′ ) , ( 0 , c ′ ) (a',b'),(0,c') (a,b),(0,c)。可以写个 m e r g e ( A , B ) merge(A,B) merge(A,B)函数用来合并 A A A B B B向量。

对于查询 ( x , y ) (x,y) (x,y)而言,若 a a a不为零,首先要满足 a ∣ x a\mid x ax,然后若 c c c不为零还要看是否满足 c ∣ ( y − x a b ) c\mid (y-\frac xab) c(yaxb)。对于为零的情况特判一下即可。

struct Node{
	ll x,y;
};
void merge(Node &a,Node &b){
	if(!a.x && !b.x){
		a.y=__gcd(a.y,b.y);
		b.x=b.y=0;
	}else if(!a.y && !b.y){
		a.x=__gcd(a.x,b.x);
		b.x=b.y=0;
	}
	while(b.x){
		ll t=a.x/b.x;
		a.x-=t*b.x,a.y-=t*b.y;
		swap(a,b);
	}
	b.y=abs(b.y);
	if(a.x<0)a.x*=-1,a.y*=-1;
	if(b.y)a.y=(a.y%b.y+b.y)%b.y;
}
bool check(Node a,Node b,Node c){
	if(a.x){
		if(c.x%a.x)return false;
		ll k=c.x/a.x;
		c.y-=a.y*k;
	}else if(c.x)return false;
	if(!b.y)return !c.y;
	return !(c.y%b.y);
}
int main(){
	int t=rd(),kase=0;
	while(t--){
		int q=rd();
		ll ans=0;
		Node a={0,0},b={0,0};
		while(q--){
			int op=rd(),x=rd(),y=rd(),w=0;
			if(op==1){
				Node c={x,y};
				merge(a,c);
				merge(b,c);
				merge(a,b);
			}else{
				w=rd();
				Node c={x,y};
				if(check(a,b,c))ans+=w;
			}
		}
		printf("Case #%d: %lld\n",++kase,ans);
	} 
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页