题目链接

题意:给定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. aperm方法

     本文原创,转载请注明出处,本人Q1273314690(交流学习) 感觉很多地方提到了aperm,但都没讲清楚,我自己参考了大家的资料,做了下总结,希望能够让对大家有所帮助. aperm方法 Tran ...

  2. ASP CDONTS.NEWMAIL组件发送电邮(附下载)

    附CDONT.NEWMAIL组件下载地址:http://files.cnblogs.com/files/colinliu/cdonts.rar ASP常规发送方法: <% dim mail se ...

  3. javascript 时间代理

    <button class="btn-active">按钮1</button> <button>按钮2</button> <b ...

  4. codevs5164 逆波兰表达式

    题目描述 Description 逆波兰表达式是一种把运算符前置的算术表达式(又叫前缀表达式),例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也 ...

  5. xcode 插件

    http://www.cocoachina.com/ios/20160122/15080.html https://github.com/rickytan/RTImageAssets http://m ...

  6. Java(Android)线程池

      1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run()  ...

  7. [Asp.net MVC]Asp.net MVC5系列——添加数据

    目录 概述 显示添加数据时所用表单 处理HTTP-POST 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net MVC5系列 ...

  8. Oracle 分区表的新增、修改、删除、合并。普通表转分区表方法

    一. 分区表理论知识 Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中.分区完全对应用透明. Orac ...

  9. [原创]使用java批量修改文件编码(ANSI-->UTF-8)

    从网上下载的项目,有时候.java文件的编码是ANSI.导入到自己的MyEclipse后,查看项目源码的时候,总是乱码. 一个个.java去修改的话, 既麻烦又不现实.所以写了下面这个工具类,进行批量 ...

  10. Android的一种MVP模式框架

    今天给大家分享的是一种将view的初始化和逻辑与activity分离的架构,采用的是mvp模式.但令人遗憾的是,这仅仅是一个新的思路,我在实际使用中发现其并不能完全将UI逻辑与activity分开,所 ...