题目链接

题意:给定n个数,这n个数的素因子值不超过2000,从中取任意个数使其乘积为完全平方数,问有多少种取法。

题解:开始用素筛枚举写了半天TLE了,后来队友说高斯消元才想起来,果断用模板。赛后又得知这是个原题sgu200,真坑啊。把每个数进行素因子分解,素因子a的幂为奇数则视为1,偶数则视为0,转化为从n个数中取数异或和为0有多少种取法的问题。

AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define maxn 305
using namespace std;
typedef long long ll;
ll T, N;
ll beg[maxn], end[maxn], x[maxn];
ll a[maxn][maxn]; ll Gauss_XOR(ll a[maxn][maxn], ll x[maxn], ll var, ll equ)
{
ll row, col;
for (row = col = ; row <= equ && col <= var; ++row, ++col)
{
if (!a[row][col])
{
for (int i = equ; i > row; --i)
{
if (a[i][col])
{
for (int j = row; j <= var + ; ++j)
{
swap(a[i][j], a[row][j]);
}
break;
}
}
}
if (!a[row][col])
{
--row;
continue;
}
for (int i = row + ; i <= equ; ++i)
{
if (a[i][col])
{
for (int j = var + ; j >= col; --j)
{
a[i][j] ^= a[row][j];
}
}
}
}
for (int i = row; i <= equ; ++i)
{
if (a[i][var + ]) return -;
}
if (row <= var)
{
return var - row + ;
}
for (int i = var; i >= ; --i)
{
x[i] = a[i][var + ];
for (int j = i + ; j <= var; ++j)
{
x[i] ^= a[i][j] && x[j];
}
}
return ;
}
const long long mod=;
ll prime[],cnt=;
ll isprime[];
ll data[][];
void get()
{
for(int i=; i<=; i++)
isprime[i]=;
for(int i=; i<=; i++)
{
if(isprime[i]==)
{
prime[cnt++]=i;
for(int j=i+i; j<=; j+=i)
isprime[j]=;
}
}
}
int main()
{
ll num;
int cas=;
get();
scanf("%lld", &T);
while (T--)
{
ll equ = ;
memset(x, , sizeof (x));
memset(a, , sizeof (a));
scanf("%lld", &N);
for(int i = ; i <= N; ++i)
{
memset(data,,sizeof(data));
ll pos = ;
scanf("%lld", &num);
ll tmp1=num,tmp2=;
for(int j=; j<cnt; j++)
{
int sum=;
if(tmp1%prime[j]==)
{
tmp1/=prime[j];
sum++;
while(tmp1%prime[j]==)
{
tmp1/=prime[j];
sum++;
}
}
if(sum%==)
data[j/][j%]=;
}
int b=;
int ii=,jj=;
while(b--)
{
if(jj==)
{
ii++;
jj=;
}
if(data[ii][jj++] & ) a[pos][i] = ;
else a[pos][i] = ;
//num >>= 1;
++pos;
}
equ = max(equ, pos - );
}
for(int i = ; i <= ; ++i)
a[i][N + ] = ;
ll ans = Gauss_XOR(a, x, N, equ);
if (ans == -) puts("-1");
else
{
ll prt = ;
for(int i = ; i <= ans; ++i)
{
prt <<= ;
prt %= mod;
}
printf("Case #%d:\n",cas++);
prt=(prt-+mod)%mod;
printf("%lld\n", prt);
}
}
return ;
}

之前写的TLE素筛:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const long long mod=;
ll prime[],cnt=;
ll isprime[],isprime2[];
ll data[][];
void get()
{
for(int i=; i<=; i++)
isprime[i]=;
for(int i=; i<=; i++)
{
if(isprime[i]==)
{
prime[cnt++]=i;
for(int j=i+i; j<=; j+=i)
isprime[j]=;
}
}
}
int main()
{
get();
//
int num[cnt+];
int t,cas=,a[];
/* ll c=1;
for(int i=0;i<15;i++)
c*=prime[i];
printf("%lld\n",b);*/
scanf("%d",&t);
while(t--)
{
int n;
memset(a,,sizeof(a));
memset(data,,sizeof(data));
scanf("%d",&n);
for(int i=; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
ll sum=,k=-,flag1=;
ll tmp1;
for(int i=; i<; i++)
{
sum=;
k=-;
flag1=;
for(int j=; j<n; j++)
{
tmp1=a[j];
if(tmp1==-) continue;
if(tmp1%prime[i]==)
{
//cout<<tmp1<<" *** "<<prime[i]<<endl;
tmp1/=prime[i];
sum++;
flag1++;
while(tmp1%prime[i]==)
{
tmp1/=prime[i];
sum++;
}
k=j;
}
if(flag1>=)
break;
}
//cout<<prime[i]<<" "<<sum<<" "<<flag1<<endl;
if(flag1==&&((sum%)==))
a[k]=-;
}
for(int i=; i<n; i++)
{
if(a[i]==-)
{
for(int j=i; j<n; j++)
{
a[j]=a[j+];
}
i--;
n--;
}
}
ll tmp=;
memset(num,,sizeof(num));
ll tmp2;
for(int i=;i<n;i++)
{
tmp=;
for(int j=;j<cnt;j++)
{
tmp2=a[i];
if(!tmp2) break;
if(tmp2%prime[j]==&&tmp2!=)
{
tmp2/=prime[j];
data[i][prime[j]]++;
while(tmp2%prime[j]==)
{
tmp2/=prime[j];
data[i][prime[j]]++;
}
data[i][prime[j]]%=;
}
}
}
// cout<<data[0][3]<<endl;
// cout<<data[1][3]<<endl;
// cout<<data[2][2]<<endl;
// for(int i=0;i<n;i++)
// {
// cout<<a[i]<<" ";
// }cout<<endl;
ll pre[];
ll ans=-;
for(int i=;i<(<<n);i++)
{
memset(pre,,sizeof(pre));
for(int j=;j<n;j++)
{
if(i&(<<j))
{
for(int x=;x<=;x++)
{
pre[x]+=data[j][x];
pre[x]%=;
}
}
}
int flag=;
for(int k=;k<cnt;k++)
{
if(pre[prime[k]]%==)
{
flag=;
break;
}
}
if(flag==)
{
//cout<<i<<"***"<<endl;
ans++;
ans%=mod;
}
}
printf("Case #%d:\n",cas++);
printf("%lld\n",ans);
}
return ;
}

HDU 5833 Zhu and 772002 (数论+高斯消元)的更多相关文章

  1. HDU 5833 Zhu and 772002 (高斯消元)

    Zhu and 772002 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5833 Description Zhu and 772002 are b ...

  2. HDU 5833 Zhu and 772002(高斯消元)

    题意:给n个数,从n个数中抽取x(x>=1)个数,这x个数相乘为完全平方数,求一共有多少种取法,结果模1000000007. 思路:每个数可以拆成素数相乘的形式,例如: x1 2=2^1 * 3 ...

  3. HDU 5833 (2016大学生网络预选赛) Zhu and 772002(高斯消元求齐次方程的秩)

    网络预选赛的题目……比赛的时候没有做上,确实是没啥思路,只知道肯定是整数分解,然后乘起来素数的幂肯定是偶数,然后就不知道该怎么办了… 最后题目要求输出方案数,首先根据题目应该能写出如下齐次方程(从别人 ...

  4. HDU 5833 Zhu and 772002

    HDU 5833 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  5. hdu 5833 Zhu and 772002 ccpc网络赛 高斯消元法

    传送门:hdu 5833 Zhu and 772002 题意:给n个数,每个数的素数因子不大于2000,让你从其中选则大于等于1个数相乘之后的结果为完全平方数 思路: 小于等于2000的素数一共也只有 ...

  6. hdu 5833 Zhu and 772002 高斯消元

    Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...

  7. HDU 5833 Zhu and 772002 ——线性基

    [题目分析] 这题貌似在UVA上做过,高精度高斯消元. 练习赛T2,然后突然脑洞出来一个用Bitset的方法. 发现代码只需要30多行就A掉了 Bitset大法好 [代码] #include < ...

  8. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

  9. 【BZOJ3601】一个人的数论 高斯消元+莫比乌斯反演

    [BZOJ3601]一个人的数论 题解:本题的做法还是很神的~ 那么g(n)如何求呢?显然它的常数项=0,我们可以用待定系数法,将n=1...d+1的情况代入式子中解方程,有d+1个方程和d+1个未知 ...

随机推荐

  1. 深入理解计算机系统-从书中看到了异或交换ab两个值的新感

    还得从一个很经典的面试题说起:不通过第三个变量来交换两个变量a,b的值... 一个很经典的答案是通过异或来解决: 第壹步:a=a^b; 第贰步:b=a^b; 第叁步:a=a^b; 以前提起" ...

  2. C#之类与对象

    这段代码告诉我们要把#define DEBUG放在文件的开头位置,不然会导致编译错误,最后还要#endif 以上代码告诉我们可以对自己创建的类设计自己的构造方法,然后可以通过具体的Main()函数来通 ...

  3. MySQL Python教程(3)

    Class cursor.MySQLCursor 具体方法和属性如下:Constructor cursor.MySQLCursorMethod MySQLCursor.callproc(procnam ...

  4. SQL Server 跨数据库查询

    语句 SELECT * FROM 数据库A.dbo.表A a, 数据库B.dbo.表B b WHERE a.field=b.field "DBO"可以省略 如 SELECT * F ...

  5. 创建第一个JBPM6项目并且运行自带的helloword例子(JBPM6学习之三)

    1. 打开Eclipse,右键New JBPM Project 项目,在项目名称里面填写一个项目名字,如“TestJbpm6”,然后下一步,知道Finish完成(里面会使用我们配置的运行环境). 2. ...

  6. Effective Java 学习笔记之所有对象都通用的方法

    一.覆盖equals时请遵守通用约定 1.满足下列任何一个条件时,不需要覆盖equals方法 a.类的每个实例本质上都是唯一的.此时就是Object中equals方法所表达的含义. b.不关心类是否提 ...

  7. 使用update!导致的更新时候的错误信息不显示 ruby on rails

    在图片管理里添加了校验方法之后,发现在更新的时候页面不显示校验报错的信息 class Picture < ApplicationRecord belongs_to :imageable, pol ...

  8. centos 修改DNS,网关,IP地址

    1.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf  修改以下内容 nameserver 8.8.8.8 #google域名服务器 nameser ...

  9. .oi 小游戏

    http://agar.io/ http://diep.io/ http://slither.io/ http://splix.io/ http://wilds.io/ http://kingz.io ...

  10. 11.3---旋转有序数组之后查找元素(CC150)

    思路,这道题用二分,唯一的不同就是,1,a[left]<a[mid].那么说明左右有序,如果key还在a[left],a[mid]之间,就在这里找,如果不在就在右边找.注意:这里<要改成& ...