码迷,mamicode.com
首页 > 其他好文 > 详细

Hdu 5833 Zhu and 772002(高斯消元解异或方程组)

时间:2016-08-16 22:04:55      阅读:427      评论:0      收藏:0      [点我收藏+]

标签:

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5833

思路:

将每个数质因数分解,若该位质因数指数为偶数,则该位a[i]为0,否则该位a[i]为1(记a[i]为质因数分解后第i个质数所对应值)。

合法方案为积的各位质因子个数对应值a[i]异或值为0。

例3=3^1,4=2^2,则3*3*4对应:

2           3

0   (1 xor 1=0)

则可列方程组

a11x1+a12x2+...+a1nxn=0

a21x1+a22x2+...+a2nxn=0

...

an1x1+an2x2+...+annxn=0

a[i][j]表示第i个质数在第j个数所对应值(奇数个为1,偶数个为0)。

x[i]表示是否选择数字i,若选择为1,否则为0。

则ans=2^(n-r)-1(r为自由变量个数,减一表示不能全为0)


#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
typedef long long LL;
const int maxn=350;
const int maxp=350;
const int maxx=2000;
const int mod=1e9+7;
struct Matrix
{
    int f[maxn][maxn];
};
Matrix e;
int v[maxx];
int n,m,q,k;
int a[maxn][maxp];
vector<int> prime;
int Guass(Matrix a,int n,int m)
{
    int i=1,j=1,k,r,u;
    while(i<=n&&j<=m)
    {
        r=i;
        for(k=i; k<=n; k++)
            if(a.f[k][j])
            {
                r=k;
                break;
            }
        if(a.f[r][j])
        {
            if(r!=i)
                for(k=0; k<=m+1; k++)
                    swap(a.f[r][k],a.f[i][k]);
            for(u=i+1; u<=n; u++)
                if(a.f[u][j])
                    for(k=i; k<=m+1; k++)
                        a.f[u][k]^=a.f[i][k];
            i++;
        }
        j++;
    }
    for(u=i; u<=n; u++)
        if(a.f[u][m+1]) return -1;
    return i-1;
}
void prepare()
{
    for(int i=2; i<maxx; i++)
    {
        if(!v[i])
        {
            prime.push_back(i);
            for(int j=i*i; j<maxx; j+=i) v[j]=1;
        }
    }
}
void change(int id,LL x)
{
    for(int i=0; i<prime.size(); i++)
    {
        while(x%prime[i]==0)
        {
            a[id][i+1]++;
            x/=prime[i];
            a[id][i+1]%=2;
        }
    }
}
LL pow_mod(LL a,LL b,LL mod)
{
   LL t=1,y=a;
   while(b)
   {
       if(b&1) t=(t*y)%mod;
       y=(y*y)%mod;
       b>>=1;
   }
   return t;
}
int main()
{
#ifdef debug
    freopen("in.in","r",stdin);
#endif // debug
    int t,cas=0;
    scanf("%d",&t);
    prepare();
    while(t--)
    {
        memset(a,0,sizeof(a));
        printf("Case #%d:\n",++cas);
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            LL x;
            scanf("%I64d",&x);
            change(i,x);
        }
        memset(e.f,0,sizeof(e.f));
        for(int i=0; i<prime.size(); i++)
            for(int j=1; j<=n; j++)
                e.f[i+1][j]=a[j][i+1];
        for(int i=0; i<prime.size(); i++) e.f[i+1][n+1]=0;
        int r=Guass(e,prime.size(),n);
        if(r==-1) printf("0\n");
        else printf("%I64d\n",pow_mod(2,n-r,mod)-1);
    }
    return 0;
}


Hdu 5833 Zhu and 772002(高斯消元解异或方程组)

标签:

原文地址:http://blog.csdn.net/wang2147483647/article/details/52224509

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!