1. 程式人生 > >codeforces 901B GCD of Polynomials (數論+構造)

codeforces 901B GCD of Polynomials (數論+構造)

Note

In the second example you can print polynomials x2 - 1 and x. The sequence of transitions is

(x2 - 1, x) → (x,  - 1) → ( - 1, 0).

There are two steps in it.

//gcd(a*x+b,a)=gcd(a,b)
//因為 b的x最高次小於a 並且逆推的話 前一項是符合係數在[-1,1]
// 那麼 a*x相當於  <<1 
//  gcd (a*x+b,a)=gcd(a*x-b,a)

(a,b)從(1,0)倒推,每次a*x+b或者 a*x-b得到下一項 (a*x+/- b,a)重複這個操作

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int p[200];
	void q() //*x 
	{
		for(int i=151;i>0;i--)
		p[i]=p[i-1];
		p[0]=0;
	}
	void f(int a[]) //+a 
	{
		for(int i=0;i<=150;i++)
		{
			p[i]+=a[i];
		}
	}
	void g(int a[]) //-2*a 
	{
		for(int i=0;i<=150;i++)
		{
			p[i]-=2*a[i];
		}
	}
	bool vj()
	{
		bool flag=true;
		for(int i=0;i<=150;i++)
		{
			if(p[i]>1||p[i]<-1)
			{
				flag=false;
				break;
			}
		}
		return flag;
	}
};
int main()
{
	int n;
	scanf("%d",&n);
	int m=n;
	int ans1[200][200];
	int ans2[200][200];
	node a,b;
	memset(a.p,0,sizeof(a.p));
	memset(b.p,0,sizeof(b.p));
	memset(ans2,0,sizeof(ans2));
	a.p[0]=1;
	memset(ans1,0,sizeof(ans1));
	ans1[0][0]=1;
	int tt=1;
	while(m--)
	{
		int t[200];
		for(int i=0;i<tt;i++)
		{
			t[i]=a.p[i];
		}
		a.q();
		a.f(b.p);
		if(!a.vj())
		{
			a.g(b.p);
		}
		for(int i=0;i<=tt;i++)
		{
			ans1[tt][i]=a.p[i];
			ans2[tt][i]=t[i];
			b.p[i]=t[i];
		}
		tt++;
	}
	printf("%d\n",n);
	for(int i=0;i<=n;i++)
	printf("%d%c",ans1[n][i],i==n?'\n':' ');
	printf("%d\n",n-1);
	for(int i=0;i<=n-1;i++)
	printf("%d%c",ans2[n][i],(i==(n-1))?'\n':' ');
}