上のビットから求めて行きます。桁DPを行います。
dp[iビット目][xがa未満確定か][yがb未満確定か] のようなdp配列を作成します。
のビット目を固定した時、のビット目も一意に定まります。
どちらも試し、のビット目がかつ、試したビットがの時にが未満が確定します。も同様です。
最後のビットまで見た時、が答えとなります。
実装ではdpのiビット目
の部分は省いています。
xxxxxxxxxx
use proconio::*;
fn solve() -> u64 {
input! {
a: u64,
b: u64,
c: u64
}
let mut dp = vec![vec![0; 2]; 2];
dp[0][0] = 1;
for d in (0..60).rev() {
let mut ndp = vec![vec![0; 2]; 2];
for da in 0..=1 {
let db = (c>>d & 1) ^ da;
// 0 -> 0 もしくは 0 -> 1の遷移が可能かどうか
let ok_a = a>>d&1 >= da;
let ok_b = b>>d&1 >= db;
// 可能な場合 0, 1 のどちらになるか
let na = if da < (a>>d&1) { 1 } else { 0 };
let nb = if db < (b>>d&1) { 1 } else { 0 };
if ok_a {
ndp[na][1] += dp[0][1];
}
if ok_b {
ndp[1][nb] += dp[1][0];
}
if ok_a && ok_b {
ndp[na][nb] += dp[0][0];
}
ndp[1][1] += dp[1][1];
}
dp = ndp;
}
dp[0][0] + dp[0][1] + dp[1][0] + dp[1][1]
}
fn main() {
input! {
t: usize,
}
for _ in 0..t {
println!("{}", solve());
}
}