zoukankan      html  css  js  c++  java
  • Sum vs XOR

    https://www.hackerrank.com/contests/hourrank-13/challenges/arthur-and-coprimes

    要求找出所有x <= n   x + n = x ^ n的个数。

    首先如果n的二进制是100101010  n = 298

    这样的话

    先考虑最高位的1,如果x在同一个位上也是1,就是x是100000000这样的话,是不行的,因为异或并不能使那一位变成0,而加法却把他们变了(进位了),所以,如果那个固定是1,那么x从100000000 --- 100101010都是不行的

    考虑第二个1,同样道理,如果这位是1,那么其它的无论怎么取也不行。

    那么现在问题就是转化为:在这么多个1中,任选若干个固定,其他的0任取什么值也没问题,有多少种方案。、

    怎么算是任选若干个呢,那么先考虑固定第二个1,然后往左统计0的个数(不统计1的个数),右边的全部当作0.

    这样贡献 +pow(2, len)。然后枚举第三个1,一路做下去即可

    这个时候如果左边还有1,那么只能在那位放0了,因为前面枚举那个位固定为1的时候,已经考虑了后面那些1的位置的两种情况,‘

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const LL one = 1;
    char str[111];
    int lenstr;
    void bin(LL n) {
        if (n / 2) {
            bin(n / 2);
        }
        str[lenstr++] = n % 2 + '0';
    }
    void work() {
    //    int n;
    //    cin >> n;
    //    int ans = 0;
    ////    cout << n << endl;
    //    for (int i = 0; i <= n; ++i) {
    //        int t = n ^ i;
    ////        cout << t << " fff" << endl;
    //        if (t == n + i) ++ans;
    //    }
    //    cout << ans << endl;
        LL n;
        cin >> n;
        LL ans = 0;
        for (int i = 62; i >= 0; --i) {
            if ((n & (one << i)) > 0) {
                ans += n - (one << i) + 1;
                break;
            }
        }
        bin(n);
        for (int i = 1; i < lenstr; ++i) {
            if (str[i] == '1') {
                int t = lenstr - 1 - i;
                for (int j = i - 1; j > 0; --j) {
                    if (str[j] == '0') t++;
                }
                ans += pow(2, t);
            }
        }
        cout << n + 1 - ans << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        work();
        return 0;
    }
    View Code

    复杂度是logn

  • 相关阅读:
    Open-Drain与Push-Pull【转】
    1.Linux电源管理-休眠与唤醒【转】
    MII、RMII、GMII接口的详细介绍【转】
    MII与RMII接口的区别【转】
    SPI总线协议及SPI时序图详解【转】
    Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比【转】
    C实战:项目构建Make,Automake,CMake【转】
    Linux 下的dd命令使用详解(摘录)【转】
    PHP数组常用函数
    Linux收藏
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5931631.html
Copyright © 2011-2022 走看看