记一道数位dp(A-A|B)

A|B
 

题目描述 

 

给定两个正整数a,x,统计满足以下条件的bb的个数:

  1. 1 \le b\le x1bx
  2. a|b=a+bab=a+b

输入描述:

第一行给出一个 t, 1\le t \le 10^5t,1t105

接下来 t 行每行一对正整数 a,x,1\le a,x \le 10^9a,x,1a,x109

输出描述:

输出 t 行,每行一个正整数

示例1

输入

2
1 2
2 3

输出

1
1


代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int dp[2][35];//数位dp,
int digit[35];
int a,x;
int solve(int x){
    memset(digit,0,sizeof(digit));
    int cnt=0,tmp=x;
    while(tmp){
        digit[++cnt]=tmp&1;
        tmp>>=1;
    }
    int ans=0;
    bool flag=0;
    for(int i=cnt;i>=1;i--){//从高位向低位;
        for(int j=0;j<digit[i];j++){
            ans+=dp[j][i];
            if((a>>(i-1))&1)
                flag=1;
        }
        if(flag)
            break;
    }
    return ans-1;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        memset(dp,0,sizeof(dp));
        cin>>a>>x;
        int aa=a;
        dp[0][0]=1;
        for(int i=1;i<=33;i++){
            if(aa&1){
                dp[0][i]=dp[0][i-1]+dp[1][i-1];
            }else{
                dp[1][i]=dp[0][i-1]+dp[1][i-1];
                dp[0][i]=dp[0][i-1]+dp[1][i-1];
            }
            aa>>=1;
        }
        cout<<solve(x+1)<<endl;
    }
}

 

posted @ 2021-03-14 22:10  xuanzo  阅读(48)  评论(0编辑  收藏  举报