SGU 200 Cracking RSA (高斯消元)

来源:互联网 发布:nba比赛个人数据统计 编辑:程序博客网 时间:2024/06/05 00:53

题意:

给出n个数的集合,这n个数的因子都是前t个质数。求这个集合有多少个子集,这个子集满足元素相乘是平方数。

题解:

高斯消元。因为都是质数,那么要得到平方数那么这些集合的元素对应的因子要成对出现,不成对不可能够成完全平方数。于是每个方程代表一个因子,设xi表示集合i元素是否有,然后列出t个式子求解。最后只要求2^(自由因子个数)。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))void cmax(int& a,int b){ if(b>a)a=b; }void cmin(int& a,int b){ if(b<a)a=b; }typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const int MOD=10007;const int maxn=105;const int maxm=105;int maze[maxn][maxn];int a[maxn],p[1005];#define eps 1e-8struct BigInt{    int num[maxm];    BigInt(){        memset(num,0,sizeof num);    }    BigInt(int a){        for(int i=0;i<maxm;i++){            num[i]=a%10;            a/=10;        }    }    BigInt operator+(const BigInt& a)const{        BigInt b;        int x=0,g=0;        for(int i=0;i<maxn;i++){            x=g+a.num[i]+num[i];            b.num[i]=x%10;            g=x/10;        }        return b;    }    BigInt operator*(int t)const{        BigInt a;        int x=0,g=0;        for(int i=0;i<maxm;i++){            x=g+num[i]*t;            a.num[i]=x%10;            g=x/10;        }        return a;    }    void sub_one(){        for(int i=0;i<maxm;i++){            if(num[i]>0){                num[i]--;                break;            }        }    }    void output(){        int i;        for(i=maxm-1;i>=0&&num[i]==0;i--);        for(;i>=0;i--)printf("%d",num[i]);        puts("");    }}pow2[maxm];int Gauss(int n,int m){    int r,c;    for(r=c=0;r<n&&c<m;r++,c++){        int id=r;        for(int i=r+1;i<n;i++){            if(maze[i][c]>maze[id][c])                id=i;        }        if(id!=r){            for(int j=c;j<=m;j++){                swap(maze[r][j],maze[id][j]);            }        }        if(maze[r][c]==0){            r--;            continue;        }        for(int i=r+1;i<n;i++){            if(maze[i][c]!=0){                for(int j=c;j<=m;j++){                    maze[i][j]^=maze[r][j];                }            }        }    }    return m-r;}void getPrime(){    memset(p,0,sizeof p);    for(int i=2;i<=1000;i++)    {        if(!p[i])p[++p[0]]=i;        for(int j=1;j<=p[0]&&p[j]*i<=1000;j++)        {            p[p[j]*i]=1;            if(i%p[j]==0)break;        }     }}void Init(){    pow2[0]=1;    for(int i=1;i<maxm;i++){        pow2[i]=pow2[i-1]*2;    }    getPrime();}int main(){    //freopen("G:\\read.txt","r",stdin);    int t,n;    Init();    while(scanf("%d %d",&t,&n)!=EOF){        for(int i=0;i<n;i++){            scanf("%d",&a[i]);        }        memset(maze,0,sizeof maze);        for(int i=0;i<t;i++){            for(int j=0;j<n;j++){                while(a[j]%p[i+1]==0){                    maze[i][j]^=1;                    a[j]/=p[i+1];                }            }        }        int id=Gauss(t,n);        BigInt ans=pow2[id];        ans.sub_one();        ans.output();    }    return 0;}/***/




0 0
原创粉丝点击