• Subsets Forming Perfect Squares


     题意:

    给出n个数字,选出若干个数字,使得这些数字的乘积是一个完全平方数,问有多少种选法。

    解法:

    考虑异或方程组,$x_i$表示第i个数字是否选,

    注意到只要保证结果中各个质因数都出现偶数次就可保证结果是一个完全平方数。

    相当于每个因数出现的次数$mod  2 = 0$。

    这样对于每一个质因子,我们可以得到一个有n个变量的异或方程。

    求矩阵中自由元的个数$cnt$,答案就是$2^{cnt}-1$

    注意本题中变量数可能远大于方程数,我们不能普通地Jordan。

    只要消成阶梯矩阵,并求出矩阵的秩即可。

    用$bitmask$压位,可以做到$O(frac{n^3}{64})$

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <bitset>
     5 
     6 #define N 2010
     7 #define LL long long
     8 #define P 1000000007LL
     9 
    10 using namespace std;
    11 
    12 bitset<N> g[N];
    13 bool v[N];
    14 int tot,prime[N];
    15 LL a[N];
    16 
    17 LL solve(int n,int m)
    18 {
    19     LL ans=1LL;
    20     int k=1; 
    21     for(int i=1;i<=m;i++)
    22     {
    23         int t=0;
    24         for(int j=k;j<=n;j++)
    25             if(g[j][i])
    26             {
    27                 t=j;
    28                 break;
    29             }
    30         if(!t)
    31         {
    32             ans=ans*2LL%P;
    33             continue;
    34         }
    35         swap(g[t],g[k]);
    36         for(int j=k+1;j<=n;j++)
    37             if(j!=k && g[j][i])
    38                 g[j]^=g[k];
    39         k++;
    40     }
    41     return (ans-1LL+P)%P;
    42 }
    43 
    44 int main()
    45 {
    46     for(int i=2;i<=2000;i++)
    47     {
    48         if(v[i]) continue;
    49         prime[++tot]=i;
    50         for(int j=i+i;j<=2000;j+=i)
    51             v[j]=1;
    52     }
    53     int T,n,Te=0;
    54     cin>>T;
    55     while(T--)
    56     {
    57         cin>>n;
    58         for(int i=1;i<=tot;i++) g[i].reset();
    59         for(int i=1;i<=n;i++)
    60         {
    61             cin>>a[i];
    62             for(int j=1;j<=tot;j++)
    63             {
    64                 LL tmp=a[i];
    65                 while(tmp%prime[j]==0)
    66                 {
    67                     g[j][i]=g[j][i]^1;
    68                     tmp/=prime[j];
    69                 }
    70             }
    71         }
    72         printf("Case #%d:
    ",++Te);
    73         cout << solve(tot,n) << endl;
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    three.js中 用 鼠标点击+呼吸灯
    socket.io学习以及在vuehtml使用,node搭建的后台
    网路在线古诗文免费阅读网站
    vue-element-admin默认加载Dashboard更改
    vue-element-admin后台框架侧边蓝图标添加自定义
    吸顶操作vue
    对图片进行裁剪(vueCropper)图片不显示
    ucharts使用内容
    文字转换为语音在线免费工具连接
    tree.js外部骨骼动画
  • 原文地址:https://www.cnblogs.com/lawyer/p/6558863.html
Copyright © 2020-2023  润新知