zoukankan      html  css  js  c++  java
  • Present CodeForces

    题目大意比较简单,就是求一堆(二元组)的异或和。

    思路:按位考虑,如果说第k位为1的话,那么一定有奇数个(二元组)在该位为1。二元组内的数是相加的,相加是可以进位的。所以第k位是0还是1,至于k为后边的数有关,所以我们直接(1<<(k+1))取模。取模后每个数的取值范围就是[0,2^(k+1)-1],二元组的取值范围就是[0,2^(k+2)-2]。

    先把二元组看成一个数x,x的第k位是1, 那么x的取值范围就是[2^k,2^(k+1)-1]和[2^k+2^(k+1),2^(k+2)-2]。

    解释一下为什么。因为x的取值为[0,2^(k+2)-2]。如果说k的左边没有1,那么取值范围就是010000...~~011111...,如果说k的左边有1,这里做多只能由一个1,如果k的左边有两个1的话那范围直接就是2^(k+2)+...肯定不对的,所以只能有一个1,那么范围就成了11000...~~11111...

    然后将对每一个arr[i],在[1,i)的范围内查找j的个数。arr[j]的范围就是x-arr[i]了。查找的时候用二分。upper_bound和lower_bound要搭配使用。寻找上边界的时候用upper_bound,寻找下边界用lower_bound,至于为啥,自己举个例子就行了....

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=4e5+7;
    int arr[N];
    int main(){ 
        int n;
        cin>>n;
        for(int i=1;i<=n;i++) cin>>arr[i];
        int ans=0;
        for(int i=26;i>=0;i--){
            for(int j=1;j<=n;j++) arr[j]=arr[j]%(1<<(i+1));
            sort(arr+1,arr+1+n);
            for(int j=1;j<=n;j++)
                {
                    if((upper_bound(arr+1,arr+j,(1<<(i+1))-1-arr[j])-lower_bound(arr+1,arr+j,(1<<i)-arr[j]))&1)
                        ans^=1<<i;
                    if((upper_bound(arr+1,arr+j,(1<<(i+2))-2-arr[j])-lower_bound(arr+1,arr+j,(1<<(i+1))+(1<<i)-arr[j]))&1)
                        ans^=1<<i;
                } 
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    「学习笔记」Min25筛
    hash索引
    Thread的setDaemon(true)方法的作用
    Reactor模式详解
    题目整理
    jstat命令查看jvm的GC情况 (以Linux为例)
    jvm参数调优
    以网游服务端的网络接入层设计为例,理解实时通信的技术挑战
    Java 工程师成神之路
    ID生成 雪花算法
  • 原文地址:https://www.cnblogs.com/Accepting/p/12680593.html
Copyright © 2011-2022 走看看