题目链接

题意:给定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. 编译本地64位版本的hadoop-2.6.0

     官方提供的hadoop-2.x版本貌似都是32位的,在64位机子下使用可能会报错,最好使用官方提供的源码进行本地编译,编译成适合本地硬件环境的64位软件包. 关于native  Hadoop是使用J ...

  2. bzoj1179 [Apio2009]Atm

    Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口 ...

  3. 繁华模拟赛day8 科技树

    /* 贪心,很明显是越容易升级的越先升级 */ #include<iostream> #include<cstdio> #include<string> #incl ...

  4. taglib

    thinkphp中 taglib标签应用 原文出处:http://blog.csdn.net/a11085013/article/details/38172653 1.配置文件中加上: 'APP_AU ...

  5. C语言中的#define预处理指令

    本文链接:http://www.cnblogs.com/xxNote/p/4009460.html 今天看C Primer Plus里面看449页里面 16.2.1语言符号 讲到从技术方面看,系统把宏 ...

  6. HDU1102--最小生成树

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. Hashtable和HashMap的区别举例

    我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable ...

  8. Droid4x安装busybox

      下载Busybox                                                                                         ...

  9. SSRS报表参数设置

    一.日期时间类型的参数注意事项: 关于数据类型的选择:(只有数据类型设置为日期/时间格式,在查询的时候才会显示日期控件,提示信息一般改成汉字) 指定默认值:指定开始日期为前10天,

  10. 常见的SQL语句

    1.select decode(a.xh,'','0','1')||decode(b.xh,'','0','1') from A a left join B b on a.xh=b.xh where ...