zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    ", orsum * qpow(2, n - 1) % Mod);
    	return 0;
    }
    
  • 相关阅读:
    celery 转自:https://www.cnblogs.com/pyedu/p/12461819.html
    k8s 学习笔记
    linux 学习笔记3
    yaml initc
    vi 块操作
    curl
    知名IT互联网公司
    ajax 上传文件给webapi(带basic认证)
    C# 后台请求api
    mvc 母版页保持不刷新
  • 原文地址:https://www.cnblogs.com/showson/p/5006747.html
Copyright © 2011-2022 走看看