bzoj 3811: 玛里苟斯 高斯消元&dfs
2016-05-09 18:17
225 查看
这道题目还要根据k来分类讨论。。。。
当k=1的时候,按位求贡献,然后发现答案就是所有数or起来再/2。
当k=2的时候,就真的要按位来了。。按照(x1+x2+...+xn)^2展开x1x1+x1x2+x1x3...+xnxn,枚举i,j表示后面式子的下标。然后一个数就变成(0/1,0/1)二元组,当选出的数二元组异或后为(1,1)的时候有2^(i+j)的贡献。显然根据k=1发现(1,1)概率应该是1/4,但特殊情况就是所有二元组都是(0,0)或者(1,1)的形式则概率为1/2。
当k>2的时候,显然每个数<=2^21,而如果一个数能通过别的数异或得到则没有用。维护一个线性基然后就只有22个数了,dfs即可。
AC代码如下:
by lych
2016.5.9
当k=1的时候,按位求贡献,然后发现答案就是所有数or起来再/2。
当k=2的时候,就真的要按位来了。。按照(x1+x2+...+xn)^2展开x1x1+x1x2+x1x3...+xnxn,枚举i,j表示后面式子的下标。然后一个数就变成(0/1,0/1)二元组,当选出的数二元组异或后为(1,1)的时候有2^(i+j)的贡献。显然根据k=1发现(1,1)概率应该是1/4,但特殊情况就是所有二元组都是(0,0)或者(1,1)的形式则概率为1/2。
当k>2的时候,显然每个数<=2^21,而如果一个数能通过别的数异或得到则没有用。维护一个线性基然后就只有22个数了,dfs即可。
AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 #define M 75 #define ll unsigned long long using namespace std; int n,flag; ll ans,res,mod,bin[M],a ,base[M]; bool f[M][M]; void calc(){ int i,j; for (i=1; i<=n; i++) for (j=31; j>=0; j--) if (a[i]&bin[j]) if (!base[j]){ base[j]=a[i]; break; } else a[i]^=base[j]; for (j=n=0; j<32; j++) if (base[j]) a[++n]=base[j]; } void solve1(){ int i,j,k,t; for (i=0; i<32; i++) for (j=1; j<=n; j++) f[i][j]=(a[j]&bin[i])?1:0; for (i=0; i<32; i++) for (j=0; j<32; j++){ for (k=1; k<=n; k++) if (f[i][k]) break; if (k>n) continue; for (k=1; k<=n; k++) if (f[j][k]) break; if (k>n) continue; t=0; for (k=1; k<=n && !t; k++) if (f[i][k]!=f[j][k]) t=1; if (i+j-1-t<0) res++; else ans+=bin[i+j-1-t]; ans+=res>>1; res&=1; } printf("%llu",ans); puts(res?".5":""); } void dfs(int k,ll now){ if (k>n){ int i; ll u=0,v=1; for (i=1; i<=flag; i++){ u*=now; v*=now; u+=v>>n; v&=mod; } ans+=u; res+=v; ans+=res>>n; res&=mod; return; } dfs(k+1,now); dfs(k+1,now^a[k]); } void solve2(){ mod=bin -1; dfs(1,0); printf("%llu",ans); puts(res?".5":""); } int main(){ scanf("%d%d",&n,&flag); int i; bin[0]=1; for (i=1; i<63; i++) bin[i]=bin[i-1]<<1; for (i=1; i<=n; i++) scanf("%llu",&a[i]); if (flag==1){ for (i=1; i<=n; i++) ans|=a[i]; printf("%llu",ans>>1); puts((ans&1)?".5":""); return 0; } calc(); if (flag==2) solve1(); else solve2(); return 0; }
by lych
2016.5.9
相关文章推荐
- Hibernate Type mismatch: cannot convert from CascadeType to CascadeType[]
- 指针函数与函数指针
- 模板模式(Template)
- Eclipse 简介
- Angularjs总结(六) 上传附件
- CentOS 6.5安装jdk1.7
- 处理Zabbix历史数据库办法二---使用MySQL表分区 推荐
- iOS与JS交互实战篇(ObjC版)
- mfc控件自适应窗口大小,随窗口大小变化而变化
- IOS开发中摇一摇是怎么实现的
- 自己搭建maven开发环境的步骤及其注意事项
- 实现一个用分子分母的格式来表示有理数的结构体rational以及相关的函数,rational结构体之间可以做加减乘除运算,运算的结果仍然是rational
- Eclipse 安装反编译插件jadclipse(经验总结)
- HDU 迷宫城堡 1269 (强连通图判定)
- 一台电脑上同启动两个Tomcat的方式
- cut、sort及uniq工具简介
- 视频资料收集
- Fragment通过广播刷新界面
- Elasticsearch配置详解、文档元数据
- 伤神!!Eclipse配置Struts2问题:ClassNotFoundException: org...dispatcher.ng.filter.StrutsPrepareAndExecuteFilter