bzoj3687: 简单题
bitset很好用的样子?
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstring> 6 #include<string> 7 8 using namespace std; 9 10 void setIO(const string& a) { 11 freopen((a + ".in").c_str(), "r", stdin); 12 freopen((a + ".out").c_str(), "w", stdout); 13 } 14 15 #include<bitset> 16 bitset<2000010> a; 17 18 int main() { 19 #ifdef DEBUG 20 freopen("in.txt", "r", stdin); 21 freopen("out.txt", "w", stdout); 22 #endif 23 24 int n, x, res = 0; 25 scanf("%d", &n); 26 a[0] = 1; 27 while(n--) { 28 scanf("%d", &x); 29 a ^= (a << x); 30 } 31 for(int i = 1; i <= 2000000; i++) { 32 if(a[i]) res ^= i; 33 } 34 printf("%d\n", res); 35 36 return 0; 37 }
顺带一提
子集异或和的算术和
nlogv做法:
考虑增量法
设cnt[i]表示1在当前数集S的所有子集异或和第i位出现的次数。
加入一个数x之后,如果x的第i为为0,那么cnt[i] <<= 1(原来是1的现在还是1,原来是0的现在还是0),否则cnt[i] += 2|S|-cnt[i](原来是0的现在变成了1,原来是1的现在变成了0)
这样我们便得到了S' = S ∪ {x}
代码如下(对1e9+7取模)
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> template<typename Q> Q &read(Q &x) { static char c, f; for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1; for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; if(f) x = -x; return x; } template<typename Q> Q read() { static Q x; read(x); return x; } typedef long long LL; const int N = 100000 + 10, mod = 1e9 + 7; int cnt[40]; int calc() { int res = 0; for(int i = 0; i <= 30; i++) { (res += (LL) cnt[i] * (1 << i) % mod) %= mod; } return res; } int main() { #ifdef DEBUG freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int n; read(n); int powers = 1; for(int i = 0; i < n; i++) { int x; read(x); for(int j = 0; j <= 30; j++) { if(x >> j & 1) (cnt[j] += (powers - cnt[j] + mod) % mod) %= mod; else (cnt[j] <<= 1) %= mod; } (powers <<= 1) %= mod; } printf("%d\n", calc()); return 0; }
来自汪神的方法:
可以做到O(n)
对于每一位,考虑上面的calc函数,若这一位出现过,直接考虑他在多少个子集异或和的结果里以1出现
假设有a个1则有n-a个0,则必须选奇数个1和任意多个0,则答案为
sigma(C(a, i)*2n-a)
=sigmaC(a, i) * 2n-a
=2a-1 * 2n-a
=2n-1.(i = 2k + 1)
那么答案就是sum_or * 2n-1.
汪神的代码:
#include<cstdio> using namespace std; void IO(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); } typedef long long ll; const int N=2e6+5,Mod=10086; int n; int orsum; ll qpow(ll a,int b){ ll c=1; while(b){ if(b&1) c=c*a%Mod; if(b>>=1) a=a*a%Mod; } return c; } void Init(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); orsum |= x; } } ll ans; int main(){ IO(); Init(); printf("%d\n", orsum * qpow(2, n - 1) % Mod); return 0; }
原文出处http://www.cnblogs.com/showson/