BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
【题目分析】
高斯消元求线性基。
题目本身不难,但是两种维护线性基的方法引起了我的思考。
void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i]) swap(a[i],a[j]); if (!a[i]) {k=i-1; break;} D(j,30,0) if (a[i]>>j & 1){ b[i]=j; F(x,1,n) if (x!=i && a[x]>>j&1) a[x]^=a[i]; break; } } }
——高斯消元求线性基
for (int i=1;i<=n;++i) for (int j=31;j>=0;--j) if ((a[i]>>j)&1){ if (!lb[j]) {lb[j]=a[i]; cnt++; break;} else a[i]^=lb[j]; }
——动态维护线性基
不会高斯消元解Xor方程组的我,直接使用了第二种方式求解,发现直接WA飞了。
(后来一想,居然过了样例)。
那么他们有什么差别呢。
我对拍了许多组,发现他们求出的线性基的大小是相同的。
但是高斯消元的线性基有一个神奇的特征,是使得该位为1的最小的数。(最小的)
那么有必要去写高斯消元吗?
显然不必要,做一个小操作就好了。
于是改了改动态维护线性基的代码,成了这个样子 ↓
for (int i=1;i<=n;++i) for (int j=31;j>=0;--j) if ((a[i]>>j)&1){ if (!lb[j]) {lb[j]=a[i]; cnt++; break;} else a[i]^=lb[j]; } for (int i=31;i>=0;--i) if (lb[i]) for (int j=i-1;j>=0;--j) if ((lb[i]>>j)&1) lb[i]^=lb[j];
——改版
神奇的AC了。线性基与高斯消元的结果相同。
考虑时间复杂度,都是log*n的,自然没什么差别,但是用哪种就是仁者见仁智者见智了。
实际上高斯消元会快一些(达不到复杂度上限),而动态维护线性基是标准的上限(雾)
【代码】
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std; #define maxn 100005 #define ll long long int read() { int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } const int mod=10086; int n,cnt=0,q; int lb[34],a[maxn]; int power(int a,int b) { // printf ("Pow %d ^ %d is ",a,b); int ret=1; while (b) { if (b&1) (ret*=a)%=mod; (a*=a)%=mod; b>>=1; } // printf("%d\n",ret); return ret; } bool cmp(int a,int b) { return a>b; } int main() { n=read(); for (int i=1;i<=n;++i) a[i]=read(); // sort(a+1,a+n+1); // for (int i=1;i<=n;++i) cout<<a[i]<<" "; cout<<endl; q=read(); // cout<<"query : "<<q<<endl; for (int i=1;i<=n;++i) for (int j=31;j>=0;--j) if ((a[i]>>j)&1){ if (!lb[j]) {lb[j]=a[i]; cnt++; break;} else a[i]^=lb[j]; } for (int i=31;i>=0;--i) if (lb[i]) for (int j=i-1;j>=0;--j) if ((lb[i]>>j)&1) lb[i]^=lb[j]; // printf("The Xor Base is %d\n",cnt); int rk=0,x=0,tmp=0; for (int j=31;j>=0;--j) if (lb[j]){ tmp++; // cout<<tmp<<":"<<lb[j]<<endl; if ((x^lb[j])>q) continue; x^=lb[j]; // printf("now add %d\n",cnt-tmp); rk=(rk+power(2,cnt-tmp))%mod; } for (int i=1;i<=n-cnt;++i) rk=(rk*2)%mod; rk++; cout<<rk<<endl; }
BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基的更多相关文章
- bzoj 2844: albus就是要第一个出场 高斯消元
LINK 题意:看题目不如看样例解释.给出有n个数的集合,对这些子集中的数求异或,升序统计所有子集得到的数(重复会被计入),询问一个数x,问这个数出现的第一个位置 思路:在这里要求一个所有可能出现的异 ...
- BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]
2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...
- 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基
[BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...
- BZOJ 2844: albus就是要第一个出场
2844: albus就是要第一个出场 Time Limit: 6 Sec Memory Limit: 128 MBSubmit: 1134 Solved: 481[Submit][Status] ...
- BZOJ 2844 albus就是要第一个出场(高斯消元)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2844 题意: 给出一个长度为n的正整数数列A.每次选出A的一个子集进行抑或(空集抑或值为 ...
- BZOJ 4004 JLOI2015 装备购买 高斯消元+线性基
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4004 Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装 ...
- bzoj 2844 albus就是要第一个出场 - 线性基
题目传送门 这是个通往vjudge的虫洞 这是个通往bzoj的虫洞 题目大意 给定集合$S$,现在将任意$A\subseteq S$中的元素求异或和,然后存入一个数组中(下标从1开始),然后从小到大排 ...
- bzoj 2844 albus就是要第一个出场 异或和出现次数 线性基
题目链接 题意 给定\(n\)个数,将其所有的子集(\(2^n\)个)的异或和按升序排列.给出一个询问\(q\),问\(q\)在该序列中第一次出现位置的下标(下标从\(1\)开始). 题解 结论 记其 ...
- BZOJ 2844 高斯消元 线性基
思路: //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using ...
随机推荐
- hdu2929 Bigger Is Better
题意 给出n根木棍,要你拼一个最大的数,并且这个数是m的倍数. 题解 显然越长的数越大.设\(dp[i][j]\)表示用i根木棍并且\(mod m = j\)的最大长度. 我们很容易想出dp方程,再用 ...
- <<< MyEclipse软件中的快捷键
-------------------------------------MyEclipse 快捷键1(CTRL)-------------------------------------Ctrl+1 ...
- Web Service 中返回DataSet结果大小改进
http://www.cnblogs.com/scottckt/archive/2012/11/10/2764496.html Web Service 中返回DataSet结果方法: 1)直接返回Da ...
- BZOJ4416: [Shoi2013]阶乘字符串
可以大胆猜想n>21时无解,至于依据,不开O2,1s,n<=21刚好能卡过去= = 并不会证= = #include<cstdio> void up(int& a,in ...
- 在eclipse中遇到cannot open output file xxx.exe: Permission denied 的解决办法
该问题出现的原因主要原因是,编译后运行的程序未能正确关闭,解决方法:删除debug目录即可 同理在vc6.0遇到同样问题时,删除debug目录,或者重启vc6.0即可
- IntelliJ IDEA 14.x 快捷键/个性化设置
常用快捷键设置(设置成跟Eclipse差不多) 按照路径:File -> Settings -> Appearance & Behavior -> Keymap -> ...
- JavaScript方法call、apply、caller、callee、bind的使用详解及区别
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). 即 “某个方法”当做“指定的某个对象”的“方法”被执行. Js代 ...
- 【Alpha】Daily Scrum Meeting第一次
一.本次Daily Scrum Meeting主要内容 代码任务细分 服务器搭建 每个人时间分配及安排 二.项目进展 学号尾数 今天做的任务 任务完成度 明天要做的任务 612 写代码框架 30% 主 ...
- ICP 算法
ICP 算法是一种点云到点云的配准方法. 在SLAM中通过空间点云的配准(可以通过相机或者3D激光雷达获取点云数据),可以估计相机运动(机器人运动,旋转矩阵R与平移向量t),累积配准,并不断回环检测, ...
- window下安装zookeeper
本地zookeeper安装(win7)下载zookeeper-3.3.6.zip文件解压zookeeper-3.3.6.zip文件到d:盘在D:\zookeeper-3.3.6\conf下增添 zoo ...