数学专项number_theory:UVa 10951

来源:互联网 发布:软件项目管理软件app 编辑:程序博客网 时间:2024/05/16 10:02

题目大意就是在n的剩余系下求两个多项式的gcd多项式。很自然的可以想到用欧几里得算法,而且n保证为质数,所以求逆也很方便。至于保存多项式,我用一个vector来从高位到低位来保存一个多项式。

#include <iostream>#include <cstdio>#include <vector>#include <algorithm>using namespace std;int pow_mod(int a,int n,int m){    if(n==0) return 1;    int ans=pow_mod(a,n/2,m);    ans=ans*ans%m;    if(n%2==1) ans=ans*a%m;    return ans;}int n;vector<int> gcd(vector<int> a,vector<int> b){    if(b.size()==0) return a;    else    {        int t=a.size()-b.size();        vector<int> c;        for(int i=0;i<=t;i++)        {            int tmp=a[i]*pow_mod(b[0],n-2,n)%n;            for(int j=0;j<b.size();j++)            {                a[j+i]=(a[j+i]-(tmp*b[j]%n)+n)%n;            }        }        int p=-1;        for(int i=0;i<a.size();i++) if(a[i]!=0) {p=i;break;}        if(p>=0) for(int i=p;i<a.size();i++) c.push_back(a[i]);        return gcd(b,c);    }}int main(){    freopen("in.txt","r",stdin);    int kase=1;    while(cin>>n&&n)    {        int n1,n2;        vector<int> p1,p2;        cin>>n1;        for(int i=0;i<=n1;i++)        {            int t;            cin>>t;            p1.push_back(t);        }        cin>>n2;        for(int i=0;i<=n2;i++)        {            int t;            cin>>t;            p2.push_back(t);        }        vector<int> v=gcd(p1,p2);        cout<<"Case "<<kase++<<": ";        cout<<v.size()-1;        int tmp=v[0];        for(int i=0;i<v.size();i++)        {            v[i]=v[i]*pow_mod(tmp,n-2,n)%n;            cout<<" "<<v[i];        }        cout<<endl;    }    return 0;}