zoukankan      html  css  js  c++  java
  • CodeForces 1323D. Present【位运算】

    传送门

    题意

    给数列 (a_1,a_2,...,a_n),求 ((a_1+a_2)oplus(a_1+a_3)oplus...oplus(a_1+a_n)oplus(a_2+a_3)oplus...oplus(a_2+a_n)oplus...oplus(a_{n-1}+a_n))
    (oplus)”为异或运算。

    题解

    思路非常巧妙的位运算思维题,div2 场里整场比赛就 100 左右个人做出来,难度对于不是非常熟悉位运算的人来说是比较大的。
    可以考虑答案的每一位是 0 还是 1。考虑第 (w) 位,如果有奇数对 (a_i+a_j) 的第 (w) 位为 (1),那么答案的 (w) 位就是 (1)
    (a_i) 的每个数小于等于 (w) 位拿出来形成 (b_i),即构造数列 (b),使 (b_i=a_i&(2^{w+1}-1))(a_i) 中大于 (w) 的位置对于 (w) 位是没有影响的嘛。可以发现现在 (b_i) 最小为 (1),最大为 (2^{w+1}-1),所以 (b_i+b_j) 取值在区间 ([2,2^{w+2}-2]) 内,而此时要使 (w) 位为 (1),那么 (b_i+b_j) 就应该在 ([2^w,2^{w+1}-1]cup[2^{w+1}+2^w,2^{w+2}-2]) 里,那如果确定了 (b_i),满足 (b_i+b_j)(w) 位为 (1)(b_j) 就在区间 ([2^w-b_i,2^{w+1}-1-b_i]cup[2^{w+1}+2^w-b_i,2^{w+2}-2-b_i]) 里,那么 (b_j) 的个数就是满足要求的 (b_i+b_j) 的对数了。那么要求这个也比较简单了,只需要将 (b) 排序,枚举 (b_i),在 (b_1,b_2,...,b_{i-1}) 中找满足要求的 (b_j) 的个数就可以了,因为 (b) 有序,所以直接用 lower_bound 和 upper_bound 可以轻松求解区间中包含的数的数量。最后如果总的 (b_j) 个数为奇数,那么答案 (w) 位就是 (1)
    复杂度 (O(NlogNlogC)),大概算一下,最坏已经到达 (2 imes 10^8) 级别了,但是CF评测机不愧是全球最快,1s多就可以跑过

    代码

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <queue>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    const int N=4e5+10;
    const int M=1e7+10;
    int n,a[N],b[N],ans;
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int w=0;w<=24;w++){
    		for(int i=1;i<=n;i++) b[i]=a[i]&(1<<w+1)-1;
    		sort(b+1,b+n+1);
    		LL temp=0;
    		for(int i=1;i<=n;i++){
    			int posl=lower_bound(b+1,b+i,(1<<w)-b[i])-b;
    			int posr=upper_bound(b+1,b+i,(1<<w+1)-1-b[i])-b;
    			temp+=posr-posl;
    			posl=lower_bound(b+1,b+i,(1<<w+1)+(1<<w)-b[i])-b;
    			posr=upper_bound(b+1,b+i,(1<<w+2)-2-b[i])-b;
    			temp+=posr-posl;
    		}
    		if(temp%2==1) ans+=(1<<w);
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    博客园
    未释放的已删除文件
    ssh连接缓慢
    剑指 Offer 38. 字符串的排列
    剑指 Offer 37. 序列化二叉树
    剑指 Offer 50. 第一个只出现一次的字符
    剑指 Offer 36. 二叉搜索树与双向链表
    剑指 Offer 35. 复杂链表的复制
    剑指 Offer 34. 二叉树中和为某一值的路径
    剑指 Offer 33. 二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12443264.html
Copyright © 2011-2022 走看看