[NOI.AC # 803] polynomial

topic

Here Insert Picture Description

Here Insert Picture Description

Thinking

We call the polynomial P is divisible by Q, if and only if there exists a polynomial A, so that Q = A · P.
Then we can define two polynomials P, Q greatest common factor, denoted by gcd (P, Q). The size here
is the degree of size as a standard of comparison, easy to prove this gcd is unique.
The AP + BQ values must be a multiple of gcd (P, Q), and can be considered to achieve this.
If not in the field but in the polynomial integer domain, then we want to extract the equivalent of the indefinite equation ax + by = gcd (a, b ), which can use the extended Euclidean algorithm.
Extended Euclidean Algorithm principle is that, for a = kb + t, if we have a set of solutions bx ty + = gcd (a, b) of the (x ', y'), then we can construct the original a solution of the equation set (y '- kx', x ').
So for this problem, we can operate in the same manner: Let P = KQ + T, then we can find the equation AQ + BT = a set of solutions gcd (Q, T) of (A ', B'), and then obtains the original a set of solutions (B '- KA', a ') issue.
The question is how to obtain K and T.
In fact, we do not really need to perform a modulo operation - we only the most significant bit of the polynomial P needs to remove each, at this time, K is a form of xk, then KQ can easily be determined by the bit operation .
Because in the sense mod 2 addition and subtraction are XOR, so we can easily be obtained by bit operation T.
So use std :: bitset maintains two polynomials can be.

Code

#include <bits/stdc++.h>
using namespace std;
bitset<100005> a,b,p,q;
int n,m,k,yjy[200005];
int main() {
	scanf("%d%d",&n,&m);
	n++;
	m++;
	for (int i=0;i<n;i++) {
		int x;
		scanf("%d",&x);
		a.set(i,x);
	}
	for (int i = 0; i < m; i++) {
		int x;
		scanf("%d",&x);
		b.set(i,x);
	}
	while (m) {
		if (n < m) {
			yjy[k++] = -1;
			swap(a,b);
			swap(n,m);
			continue;
		}
		yjy[k++] = n - m;
		a ^= (b << (n - m));
		while (n && !a[n - 1]) n--;
	}
	p.set(0);
	for (int i = k - 1; i >= 0; i--) {
		if (yjy[i] == -1) swap(p,q);
		else q ^= (p << yjy[i]);
	}
	int n1 = 100005,m1 = 100005;
	while (n1 > 1 && !p[n1 - 1]) n1--;
	while (m1 > 1 && !q[m1 - 1]) m1--;
	printf("%d %d\n",n1 - 1,m1 - 1);
	for (int i = 0; i < n1; i++) printf("%d%c",(int)p[i]," \n"[i == n1 - 1]);
	for (int i = 0; i < m1; i++) printf("%d%c",(int)q[i]," \n"[i == m1 - 1]);
	return 0;
}
Published 703 original articles · won praise 392 · Views 140,000 +

Guess you like

Origin blog.csdn.net/Eric1561759334/article/details/104078127