zoukankan      html  css  js  c++  java
  • Xor Sum题解>----(思维+递归)

    Xor Sum AtCoder - 2272


    Time limit : 2sec / Memory limit : 256MB

    Score : 600 points

    Problem Statement

    You are given a positive integer N. Find the number of the pairs of integers u and v (0≦u,v≦N)such that there exist two non-negative integers a and b satisfying a xor b=u and a+b=v. Here, xor denotes the bitwise exclusive OR. Since it can be extremely large, compute the answer modulo 109+7.

    Constraints

    1≦N≦1018

    Input

    The input is given from Standard Input in the following format: N

    Output

    Print the number of the possible pairs of integers u and v, modulo 109+7.

    Sample Input 1

    3
    

    Sample Output 1

    5
    

    The five possible pairs of u and v are:

    u=0,v=0 (Let a=0,b=0, then 0 xor 0=0, 0+0=0.)

    u=0,v=2 (Let a=1,b=1, then 1 xor 1=0, 1+1=2.)

    u=1,v=1 (Let a=1,b=0, then 1 xor 0=1, 1+0=1.)

    u=2,v=2 (Let a=2,b=0, then 2 xor 0=2, 2+0=2.)

    u=3,v=3 (Let a=3,b=0, then 3 xor 0=3, 3+0=3.)

    Sample Input 2

    1422
    

    Sample Output 2

    52277
    

    Sample Input 3

    1000000000000000000
    

    Sample Output 3

    787014179
    

    Solution

    题意:给出正整数N,求出整数对uv (0≤u,v≤N)的数目,使得存在两个非负整数ab满足a xor b = ua + b= v。这里,xor表示按位异或。对答案取模10^9 + 7

    这是一道dp题,由于a+b = (a & b) <<1 + a ^ b,故可知a ^ b定然小于a+b,故本题可以化为寻找对于a+b<=n中a b 的个数。(当然 0 和 1 与 1 和 0是1种情况)

    首先可以使用暴力的手段得知,当n=0的时候,答案为1,n=1的时候,答案为2。对于a与b(化作二进制来看),两者的末位和有0,1,2三种情况,设a+b=x,令a = a1 * 2+a2, b = b1 * 2 + b2,a2+b2即为两者的末位和,又有x<=n,故a1+a2<=(n-a1-a2)/2,可以得出递推式 f[x] = f[x/2] + f[(x-1)/2] + f[(x-2)/2];

    Code

    #include <cstdio>
    #include <map>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <string>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    const ll maxn=1e18+5;
    map <ll,ll> f;//n范围这么大,开数组开不下......
    ll Fc(ll x){
    	if(f[x])return f[x];
    	return f[x]=(Fc(x>>1)+Fc((x-1)>>1)+Fc((x-2)>>1))%mod;//这里用位移是比'/'快,当然也更好理解
    }
    int main(){
    	ll n;
    	scanf("%lld",&n);
    	f[0]=1;f[1]=2;
    	printf("%lld
    ",Fc(n));
    	return 0;
    }
    
  • 相关阅读:
    java Activiti 工作流引擎 SSM 框架模块设计方案
    自定义表单 Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    数据库设计的十个最佳实践
    activiti 汉化 stencilset.json 文件内容
    JAVA oa 办公系统模块 设计方案
    java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端
    集成 nacos注册中心配置使用
    “感恩节 ”怼记
    仓颉编程语言的一点期望
    关于System.out.println()与System.out.print("\n")的区别
  • 原文地址:https://www.cnblogs.com/Lour688/p/12870452.html
Copyright © 2011-2022 走看看