codeforces 895C Square Subsets 线性基 或 状压DP
来源:互联网 发布:raphael min.js 下载 编辑:程序博客网 时间:2024/05/23 15:24
简略题意:n个数,问有多少选择的方法能够使得这些数的乘积变成完全平方数。
把每个数唯一分解之后,用其质因子以及其对应的幂来表示这个数。如果若干个数乘积想要位完全平方数,那么势必要使得相乘后的每一个质数的幂为偶数。
那么我们选择这个数的时候只需要在意他的所有质因子的幂次的奇偶性即可。
因为数的大小只有70,至多只会有19种质因子,可以状态压缩。因此如果一个数的质因子的幂次为奇数,就可以用1来表示对应位。
我们现在就是想取若干个数相乘使得每个质因子的幂次都为偶数,而%2意义下的加法是异或运算。
原问题转变成了从n个数中选取若干个数使得他们的异或值变为0的方案数,这就是经典的线性基问题。
那么我们可以得到一个n * 19大小的矩阵,只需要算出这个矩阵的秩,即为线性无关组的大小(线性基的大小)x,那么自由变元的大小即为n - x。
方案数即为
#define others#ifdef poj#include <iostream>#include <cstring>#include <cmath>#include <cstdio>#include <algorithm>#include <vector>#include <string>#endif // poj#ifdef others#include <bits/stdc++.h>#endif // others//#define file#define all(x) x.begin(), x.end()using namespace std;const double eps = 1e-8;int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};typedef long long LL;namespace solver { int n; const LL maxn = 110000; const LL mod = 1e9+7; int a[maxn]; bool isp(int x) { if(x <= 1) return 0; for(int i = 2; i <= sqrt(x); i++) if(x % i == 0) return 0; return 1; } vector<int> p, base; void solve() { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 1; i <= 70; i++) if(isp(i)) p.push_back(i); for(int i = 1; i <= n; i++) { int val = 0; for(int j = 0; j < p.size(); j++) { int v = a[i]; int cnt = 0; while(v % p[j] == 0) { cnt++; v /= p[j]; } if(cnt & 1) val |= 1 << j; } for(int j = 0; j < base.size(); j++) val = min(val, val ^ base[j]); if(val) base.push_back(val); } LL ans = 1; for(int i = 0; i < n - base.size(); i++) { ans *= 2, ans %= mod; } cout<<(ans-1)<<endl; }}int main() { #ifdef file freopen("gangsters.in", "r", stdin); freopen("gangsters.out", "w", stdout); #endif // file solver::solve(); return 0;}
找什么最大线性无关组啊?
70个数,(1<<19)的状态,记录下个数直接DP啊?
#define others#ifdef poj#include <iostream>#include <cstring>#include <cmath>#include <cstdio>#include <algorithm>#include <vector>#include <string>#endif // poj#ifdef others#include <bits/stdc++.h>#endif // others//#define file#define all(x) x.begin(), x.end()using namespace std;const double eps = 1e-8;int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};typedef long long LL;namespace solver { LL n; const LL mod = 1e9+7; const LL maxn = 110000; LL v[maxn]; LL pow2[maxn]; bool isp(LL x) { if(x <= 1) return 0; for(LL i = 2; i <= sqrt(x); i++) if(x % i == 0) return 0; return 1; } vector<LL> p; LL sta[maxn]; LL dp[2][(1<<20)]; LL sum[77]; void solve() { scanf("%d", &n); for(LL i = 1; i <= n; i++) { scanf("%d", &v[i]); } for(LL i = 1; i <= 70; i++) if(isp(i)) p.push_back(i); for(LL i = 1; i <= n; i++) { sum[v[i]] ++; for(LL j = 0; j < p.size(); j++) { LL val = v[i]; LL cnt = 0; while(val % p[j] == 0) { cnt++; val /= p[j]; } if(cnt & 1) sta[v[i]] |= (1 << j); } } pow2[0] = 1; for(LL i = 1; i < maxn; i++) pow2[i] = pow2[i-1] * 2 % mod; dp[0][0] = 1; for(LL i = 1; i <= 70; i++) { int now = i & 1, pre = now ^ 1; memset(dp[now], 0,sizeof dp[now]); for(LL j = 0; j < (1 << 19); j++) { if(sum[i] == 0) { dp[now][j] = dp[pre][j]; } else { LL v = pow2[sum[i]-1]; dp[now][j] += v * dp[pre][j]; if(dp[now][j] >= mod) dp[now][j] %= mod; dp[now][j] += v * dp[pre][j^sta[i]]; if(dp[now][j] >= mod) dp[now][j] %= mod; } } } cout<<dp[0][0]-1<<endl; }}int main() { #ifdef file freopen("gangsters.in", "r", stdin); freopen("gangsters.out", "w", stdout); #endif // file solver::solve(); return 0;}
阅读全文
0 0
- codeforces 895C Square Subsets 线性基 或 状压DP
- CF 895C. Square Subsets DP(状压,平方数)
- CF895C:C. Square Subsets(状压dp)
- Codeforces Round #448 (Div. 2): C. Square Subsets(线性基)
- Codeforces Round #448 (Div. 2) C. Square Subsets(状压)
- cf 895C Square Subsets
- Codeforces Round #448 (Div. 2) C. Square Subsets
- Codeforces Round #448 (Div. 2) C. Square Subsets
- Codeforces Round #448 (Div. 2) C. Square Subsets
- Codeforces895C. Square Subsets
- codeforces895C Square Subsets
- codeforces 710C C. Magic Odd Square
- Codeforces Round #367 (Div. 2) C. Hard problem 朴素dp、线性dp
- codeforces 418 C Square Table (随机算法)
- codeforces 710C Magic Odd Square
- 【模拟】Codeforces 710C Magic Odd Square
- Codeforces 710C-Magic Odd Square
- Codeforces Problem 710C Magic Odd Square
- Uber投资新进展,传软银下周公布购股报价
- DeepMind 最新进展:利用AI治疗乳腺癌
- About Messages and Message Queues
- 开发者的4个层级和6大差异
- 从0开始搭建自动部署环境(续)
- codeforces 895C Square Subsets 线性基 或 状压DP
- [C#] 谈谈异步编程async await
- 明佳巴巴新管理之“经营人”
- 用C语言实现一个自己的文件拷贝工具
- Nature Reviews:拥抱未知:解析土壤微生物组的复杂性
- pickle 在python 2和python 3中兼容性问题
- 如何用TensorFlow在安卓设备上实现深度学习推断
- 计算机视觉这一年:这是最全的一份CV技术报告
- Made in China的飞行出租车明年或将在迪拜正式运营