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/

浙公网安备 33010602011771号