codeforces 251D
2016-04-08 22:25
246 查看
题目描述
给你n≤105n\leq10^5个数,让你分成两个集合,设第一个集合的数的异或值为x1x1,第二个集合的数的异或值为x2x2,空集的异或和定义为00,让你求一个使得x1+x2x1+x2的值最大,并且满足最大条件下x1x1的值最小的方案。解题思路
首先你会发现,如果二进制中第ii位一共有奇数个11,那么这一位一定会给答案增加2i2^i的贡献,因为奇数个11分成两堆,一定有一堆为奇数个,一堆为偶数个。如果二进制中第ii位有偶数个11,那么我肯定尽量使得两堆都分得奇数个11,那么这一位就会对答案贡献2∗2i2*2^i,而且肯定是尽量满足高位。
这样的话就可以得到6060个异或方程。
例如:
a1,1∗x1⊕a2,1∗x2⊕...⊕an,1∗xn=f1a_{1,1}*x_1⊕a_{2,1}*x_2⊕...⊕a_{n,1}*x_n=f_1
…
ai,ja_{i,j}表示第ii个数的第jj位是否为11,⊕⊕表示异或,若这一位一共有奇数个11,那么ff值为0,否则为1.
参考代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bitset> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define maxn 100005 #define maxsq 62 #define ll long long using namespace std; bitset<maxn> f[maxsq+5],g[maxsq+5]; int n,tot; int ans[maxn]; ll sum; int p[maxsq+5]; int main(){ scanf("%d",&n); fo(i,1,n) { ll x; scanf("%I64d",&x); sum ^= x; fo(j,0,maxsq) if (x & (1ll << j)) g[j][i]=1; } fo(bit,0,1) { fd(i,maxsq,0) if (((sum >> i) & 1)==bit) { f[++tot]=g[i]; if (bit==0) f[tot][n+1]=1; else f[tot][n+1]=0; fo(j,1,tot-1) if (f[tot][p[j]]) f[tot] ^= f[j]; p[tot]=n+2; fo(j,1,n) if (f[tot][j]) { p[tot]=j; break; } if (p[tot]>n) { tot--; continue; } fo(j,1,tot-1) if (f[j][p[tot]]) f[j] ^= f[tot]; } } fo(i,1,tot) ans[p[i]]=f[i][n+1]; fo(i,1,n) printf("%d ",2-ans[i]); return 0; }
相关文章推荐
- FILE、inode、fork和vfork
- 吃汉堡
- 一个项目包括哪些流程?又怎样提高一个开发项目效率?
- ACM内部函数--数学问题--大数相减
- altium designer怎么在原理图中批量修改元件封装
- 大叔 Frameworks.Entity.Core 3 Predicate
- css清除浮动
- ubuntu14.10安装配置jdk
- 晕车
- 用servlet写的学生登录注册
- TDGA-需求分析
- 0408结对汉堡-结对2.0
- 3-jQuery - AJAX get()
- 幻影粒子particleIllusion—简单做特效
- 计划任务
- 10015---Synchronization Guide
- c++ set 常用用法介绍
- Angular 2知识整理第一篇 Hello,world!
- Scrapy设置之Analysis
- Android API讲解之:BitmapFactory