Zhu and 772002

    xiaoxiao2025-07-07  4

    

    Zhu and 772002

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 458    Accepted Submission(s): 151 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the ability of 772002, so he asks 772002 to solve a math problem. But 772002 has a appointment with his girl friend. So 772002 gives this problem to you. There are n numbers a1,a2,...,an . The value of the prime factors of each number does not exceed 2000 , you can choose at least one number and multiply them, then you can get a number b . How many different ways of choices can make b is a perfect square number. The answer maybe too large, so you should output the answer modulo by 1000000007 .   Input First line is a positive integer T , represents there are T test cases. For each test case: First line includes a number n(1n300) ,next line there are n numbers a1,a2,...,an,(1ai1018) .   Output For the i-th test case , first output Case #i: in a single line. Then output the answer of i-th test case modulo by 1000000007 .   Sample Input 2 3 3 3 4 3 2 2 2   Sample Output Case #1: 3 Case #2: 3   Author UESTC   Source 2016中国大学生程序设计竞赛 - 网络选拔赛 题解:

    300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案。

    合法方案的每个数的质因数的个数的奇偶值异或起来为0。

    比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3的个数是奇数为1),3的对应奇偶值为01,于是12*3是完全平方数。

    然后异或方程组就是:

    a11x1+a12x2+...+a1nxn=0

    a21x1+a22x2+...+a2nxn=0

    ...

    an1x1+an2x2+...+annxn=0

    aij:第i个质数(2000内有303个质数)在第j个数里是奇数个则为1,否则为0。

    xi:第i个数(最多300个数)被选则为1,否则为0。

    求出有多少种解即可。(异或方程组高斯消元求秩,然后解就有2^(n-rank)种,减去全为0的解)

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <cstdio> #include <cstring> #include <algorithm> #define ll long long #define mod 1000000007 using namespace std; const int N=2000; const int M=310; int prime[N+1],cnt; int n,t,mat[M][M]; ll a[M]; void getPrime(){      for ( int i=2;i<=N;i++){          if (!prime[i])prime[++cnt]=i;          for ( int j=1;j<=cnt&&prime[j]<=N/i;j++){              prime[prime[j]*i]=1;              if (i%prime[j]==0) break ;          }      } } int Rank( int c[][M]){ //异或版的高斯消元求秩      int i=0,j=0,k,r,u;      while (i<=cnt&&j<=n){          r=i;          while (c[r][j]==0&&r<=cnt)r++;          if (c[r][j]){              swap(c[i],c[r]);              for (u=i+1;u<=cnt;u++) if (c[u][j])                  for (k=i;k<=n;k++)c[u][k]^=c[i][k];              i++;          }             j++;      }      return i; } int solve(){      memset (mat,0, sizeof mat);      for ( int i=1;i<=n;i++)          for ( int j=1;j<=cnt;j++){              ll tmp=a[i];              while (tmp%prime[j]==0){                  tmp/=prime[j];                  mat[j][i]^=1;              }          }      int b=n-Rank(mat); //b个自由元      ll ans=1;      ll k=2;      while (b){          if (b&1){              ans=ans*k%mod;          }          k=k*k%mod;          b>>=1;      }      return ans-1; //减去全为0的解 } int main() {      getPrime();      scanf ( "%d" ,&t);      for ( int cas=1;cas<=t;cas++){          scanf ( "%d" ,&n);          for ( int i=1;i<=n;i++)              scanf ( "%lld" ,&a[i]);          printf ( "Case #%d:\n%d\n" ,cas,solve());      }      return 0; }

      原来是白书上的题(160页)I good vagetable a!

     
    转载请注明原文地址: https://ju.6miu.com/read-1300456.html
    最新回复(0)