• CodeForces 626 DIV.2 D Present


    题目

    题解: 现场想到了从结果的二进制的每一位考虑,每一位都是由比它低的低位决定的,但是规律没找好。
    举个例子,结果的二进制的第3位(从0位开始)上是否为1,是由0 到 2^4-1 之间的数决定,就是 0000 - 1111 之间所有数两两相加决定的,所以数组要先对2^4取余。
    而相加的结果,只有在1000 到 1111 ,也就是8~15之间,才会让第3位为1,统计为1的结果若是奇数,则最终结果的第三位上就是1,否则为0
    对 0 来说,和1000-1111 任意的数字相加,都会让第3位为1
    对 0001 来说,和0111- 1110之间的任意数字相加,也满足条件
    0010 ~ 0110-1101
    ...
    1111 ~ 0000-0000 和 1001~1111
    总的来说,考虑第3位,对任意的x(x在0~2^4-1之间), 就是看看在[2^3-x ~ 2^4-x]和[2^4-1+2^3-x,2^4-1]两个区间里有多少个数字。求区间和,可以用树状数组。
    考虑第k为,对于任意的x(x在0~2^(k+1)-1 之间),统计[2^k-x,2^(k+1)-x] 和 [2^(k+1)+2^k -x-1,2^(k+1)-1] 这两个区间的和.
    因为数组里数字的范围是10^7,任意两个数字之和最大是2*10^7,所以我最多考虑到第24位,2^24。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <set>
    #include <queue>
    #include <math.h>
    
    using namespace std;
    
    #define MAX (int)4e5+5
    #define MAX2 (1<<25)
    int a[MAX];
    int c[MAX2+5];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void Add(int pos,int len,int x)
    {
        while(pos<=len)
        {
            c[pos]+=x;
            pos+=lowbit(pos);
        }
    }
    int sum(int pos)
    {
        if(pos<=0)
            return 0;
        int res=0;
        while(pos>0)
        {
            res+=c[pos];
            pos-=lowbit(pos);
        }
        return res;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
    
        int ans=0;
        int num=1;
        for(int i=0;i<25;i++)
        {
            num<<=1;
            memset(c,0,num*sizeof(int));
            int res=0;
            for(int j=0;j<n;j++)
            {
                int x = a[j]%num;
                int xx = sum((num-1)-x+1);
                int yy = sum((num>>1)-x);
    
                res+= xx-yy;
    
                if(x>num>>1) {
    
                    xx = sum(num);
                    yy = sum(num-(x-(num>>1)));
                    res+=xx-yy;
                }
    
                if(res&1)
                {
                    res=1;
                }
                else
                    res=0;
    
                Add(x+1,num,1);
            }
    
            if(res&1)
                ans |= (1<<i);
        }
    
        printf("%d
    ",ans);
    
        return 0;
    }
    
  • 相关阅读:
    技术为辅,思维主导
    阶段性目标的设置
    非计算机专业测试之路
    第四章 Appium真机运行测试用例讲解
    第三章 Appium API介绍
    第二章 测试环境搭建(下)
    第二章 测试环境搭建(上)
    第一章 Appium简介
    测试人员的工作经验值钱吗
    2017 年该学习的编程语言、框架和工具
  • 原文地址:https://www.cnblogs.com/dacc123/p/12541714.html
Copyright © 2020-2023  润新知