【JZOJ 3823】【NOIP2014模拟9.9】遇见
来源:互联网 发布:json日期格式化输出 编辑:程序博客网 时间:2024/05/16 14:34
Description
Zyh独自一人在街上漫步。Zyh相信不久后应该就可以和她一起漫步,可是去哪里寻找那个她呢?Zyh相信每个人都有一个爱情的号码牌,这个号码牌是一个n*n的矩阵。
每个人都要在矩阵中选择若干个元素,使得每行每列都有奇数个数被选中,且选中的数字的乘积是完全平方数。每当选出了这若干个元素,他/她就能找到那个她/他。
Zyh想知道对于一个号码牌有多少种选择的方法,使得zyh能够不再孤独。由于这个数字很大,只要输出对1,000,000,007取模后的余数即可。
Data Constraint
第一类:对于30%的数据 n<=4 Aij<=10
第二类:对于50%的数据 n<=10 n*n个数分解质因数后的不同素数个数不超过5个
第三类:对于80%的数据 n<=15 Aij<=1000000000
第四类:对于100%的数据 n<=30 Aij<=1000000000
在第三类(不属于第二类)的数据中 有10%的数据满足Aij都为同一个素数
Solution
这是我第一次打高斯消元,可一上来就是一道高斯消元异或方程组……
我们可以把所有约束变成一道道异或方程。
1、对于每行每列都有奇数个数被选中的约束。我们可以把第i行的每个未知数配上一个系数1。举个例子,第i行的式子为
2、对于最终要求完全平方,我们可以拆解成n个质因数的指数为偶数。所以我们可以将n*n个数每个未知数的系数为它最多是该质因数的几次幂的倍数,例如36就是2的2次幂的倍数,同时36是3的2次幂的倍数。每个质因数也同样可以列出一个式子。
最后只要将这些高斯消元一下即可。
一些小问题
1、要注意,我们找不到当前第i位为1的式子时,我们可以将一条无意义式子(即类似0^0^0^……^0=0)移上第i位。
2、式子有可能无解。当最后你发现存在式子(类似0^0^0^……^0=1)时,则为无解。因为你不能什么都不选。
Code
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define ll long longusing namespace std;const int maxn=2005,maxn1=35,mo=1e5+5,mo1=1e9+7;int f[maxn][1000],n,i,t,j,k,l,a[maxn1][maxn1],num,h[mo],b[maxn],x,y,c[maxn],d[maxn],ans,p;void hash(int x){ int t=x%mo; while (h[t]!=x && h[t]) t=(t+1)%mo; if (!h[t]) h[t]=x,b[++b[0]]=x;}ll mi(int x){ if (x==1) return 2;if (!x) return 1; ll t=mi(x/2); if (x%2) return t*t%mo1*2%mo1;return t*t%mo1;}int main(){// freopen("data.in","r",stdin); scanf("%d",&n); for (i=1;i<=n;i++) for (j=1;j<=n;j++) scanf("%d",&a[i][j]); t=a[1][1];k=0; for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (a[i][j]==t) k++; if (k==n*n && t>1 && (n%2)){ printf("0\n"); return 0; } for (i=1;i<=n;i++){ for (j=(i-1)*n+1;j<=i*n;j++) f[i][j]=1; f[i][n*n+1]=1; } num=n; for (i=1;i<=n;i++){ ++num; for (j=i;j<=n*n;j+=n) f[num][j]=1; f[num][n*n+1]=1; } for (i=1;i<=n;i++) for (j=1;j<=n;j++){ t=sqrt(a[i][j]);l=a[i][j]; for (k=2;k<=t;k++){ if (k*k>l) break; if (l%k) continue; hash(k); while (!(l%k)) l/=k; } if (l>1) hash(l); } for (k=1;k<=b[0];k++){ ++num; for (i=1;i<=n;i++) for (j=1;j<=n;j++){ t=a[i][j];l=0; while (!(t%b[k])) t/=b[k],l++; f[num][(i-1)*n+j]=l%2; } f[num][n*n+1]=0; } while (num<n*n){++num; for (j=1;j<=n*n+1;j++) f[num][j]=f[1][j]; } for (j=1;j<=n*n;j++){ for (i=j;i<=num;i++) if (f[i][j]){ for (k=j;k<=n*n+1;k++) swap(f[i][k],f[j][k]); break; } for (i=j+1;i<=num;i++){ if (!f[i][j]) continue; for (k=j;k<=n*n+1;k++) f[i][k]=(f[i][k]^f[j][k]); } if (!f[j][j]){ t=1e9; for (i=j;i<=num;i++){ k=j; while (!f[i][k] && k<=n*n) k++; if (k==n*n+1) k=j-1; if (k<t) t=k,p=i; } for (k=j;k<=n*n+1;k++) swap(f[p][k],f[j][k]); } } for (j=num;j>=1;j--){ t=f[j][n*n+1]; if (!t) continue; for (k=1;k<=n*n;k++) if (f[j][k]) break; if (k==n*n+1){ printf("0\n");return 0; } } for (j=n*n;j>=1;j--){ t=f[j][n*n+1]; for (k=j+1;k<=n*n;k++) t=(t^(f[j][k]*c[k])); if (t) c[j]=1; else if (!f[j][j]) ans++; } ans=mi(ans); printf("%d\n",ans);}
- JZOJ 3823【NOIP2014模拟9.9】遇见
- 【JZOJ 3823】【NOIP2014模拟9.9】遇见
- JZOJ 3823. 【NOIP2014模拟9.9】遇见
- JZOJ 3822. 【NOIP2014模拟9.9】逆光
- JZOJ 3824【NOIP2014模拟9.9】渴
- JZOJ NOIP2014模拟 8.12
- JZOJ NOIP2014模拟 8.13
- 【JZOJ 3823】 遇见
- jzoj NOIP2014提高组模拟8.9总结
- [JZOJ 3794]. 【NOIP2014模拟8.20】高级打字机
- 【JZOJ】 【NOIP2014】【模拟试题】保镖排队
- JZOJ 3808. 【NOIP2014模拟8.25】道路值守
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3814. 【NOIP2014模拟9.7】天黑黑
- JZOJ 3839【NOIP2014模拟9.14】Baby Step
- 微信小程序免费HTTPS证书申请搭建教程(1)---申请SSL
- Gym - 101102J J. Divisible Numbers 位运算+优化+前缀和
- 78. Subsets**
- JAVA设计模式--访问者模式
- PAT-B 1065. 单身狗
- 【JZOJ 3823】【NOIP2014模拟9.9】遇见
- JZOJ 3839【NOIP2014模拟9.14】Baby Step
- Unix高级编程:动态加载、错误处理、进程映像
- PAT-B 1064. 朋友数
- 匿名函数应用鼠标点击事件
- postgres直接查看function返回的游标数据
- controller方法的返回值
- Java不仅仅是一门编程语言
- linux初始配置