hdu 5833 Zhu and 772002 异或方程组高斯消元

ccpc网赛卡住的一道题

蓝书上的原题 但是当时没看过蓝书

今天又找出来看看 其实也不是特别懂 但比以前是了解了一点了

主要还是要想到构造异或方程组 异或方程组的消元只需要xor就好搞了

数学真的是硬伤啊…… 

(链接:蓝书161页详细讲解 我也在看…… 

 

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<string>
  7 #define cl(a,b) memset(a,b,sizeof(a))
  8 #define debug(x) cerr<<#x<<"=="<<(x)<<endl
  9 using namespace std;
 10 typedef long long ll;
 11 
 12 const int maxn=3e2+10;
 13 const int maxx=2e3+10;
 14 const int mod=1e9+7;
 15 
 16 int n,maxp,tol;
 17 int prime[maxn];
 18 int A[maxn][maxn];
 19 
 20 ll powmod(ll a,ll x)
 21 {
 22     ll t=1;
 23     while(x)
 24     {
 25         if(x&1) t=t*a%mod;
 26         a=a*a%mod;
 27         x>>=1;
 28     }
 29     return t;
 30 }
 31 
 32 void init()
 33 {
 34     bool notprime[maxx];
 35     cl(notprime,false);
 36     notprime[0]=notprime[1]=true;
 37     for(int i=0; i<maxx; i++)
 38     {
 39         if(!notprime[i])
 40         {
 41             if(i*i>maxx) continue;
 42             for(int j=i*i; j<maxx; j+=i)
 43                 notprime[j]=true;
 44         }
 45     }
 46     tol=0;
 47     for(int i=2; i<maxx; i++)
 48         if(!notprime[i]) prime[tol++]=i;
 49 }
 50 
 51 ll Gauss(int m)
 52 {
 53     int i=0,j=0,r;
 54     while(j<m&&i<n)
 55     {
 56         r=i;
 57         for(int k=i; k<m; k++)
 58             if(A[k][j]){r=k;break;}
 59         if(A[r][j]){
 60             if(r!=i) for(int k=0; k<=n; k++) swap(A[r][k],A[i][k]);
 61             for(int u=i+1; u<m; u++) if(A[u][j])
 62                     for(int k=i; k<=n; k++) A[u][k]^=A[i][k];
 63             i++;
 64         }
 65         j++;
 66     }
 67     return i;
 68 }
 69 
 70 int main()
 71 {
 72     int T,cas=1;
 73     scanf("%d",&T);
 74     init();
 75     while(T--)
 76     {
 77         int maxp=0;
 78         ll x;
 79         scanf("%d",&n);
 80         memset(A,0,sizeof(A));
 81         for(int i=0; i<n; i++)
 82         {
 83             scanf("%lld",&x);
 84             for(int j=0; j<tol; j++)
 85             {
 86                 while(x%prime[j]==0)
 87                 {
 88                     maxp=max(maxp,j);
 89                     x/=prime[j];
 90                     A[j][i]^=1;
 91                 }
 92             }
 93         }
 94         ll r=Gauss(maxp+1);
 95         ll tmp=n-r;
 96         ll ans=powmod(2,tmp)-1;
 97         printf("Case #%d:\n",cas++);
 98         printf("%lld\n",ans);
 99     }
100     return 0;
101 }
102 
103 /*
104 
105 3
106 4
107 4 6 10 15
108 3
109 3 3 4
110 3
111 2 2 2
112 
113 */

 

posted @ 2017-01-12 22:49  良将ℓ  阅读(170)  评论(0编辑  收藏  举报