题目大意:给一数N,在区间[L, U]上找到一个数M使得M| N的值最大,如果有M有多个可能值,取最小的那个值。
从最高位开始逐位判断,如果N的该位为0,为使M | N的值最大,M的该位应考虑置为1,然后判断M的该位为1时的可能取值区间[lmin, lmax],如果区间[lmin, lmax]与区间[L, U]有交集,则说明该位可置为1;如果N的该位为1,为使M的值尽可能小,M的该位应考虑置为0,然后判断可能取值区间与[L, U]是否有交集,如果没有交集,该位置为1。
1 #include2 3 int main() 4 { 5 #ifdef LOCAL 6 freopen("in", "r", stdin); 7 #endif 8 long long d[35]; 9 d[0] = 1;10 for (int i = 1; i <= 32; i++)11 d[i] = d[i-1] * 2;12 long long N, L, U;13 while (scanf("%lld%lld%lld", &N, &L, &U) != EOF)14 {15 int a[32] = { 0};16 for (int i = 0; N > 0; i++)17 {18 a[i] = N % 2;19 N /= 2;20 }21 long long lmax, lmin, ans = 0;22 for (int i = 31; i >= 0; i--)23 {24 if (a[i] == 0)25 {26 lmin = ans + d[i];27 lmax = ans + d[i+1] - 1;28 if (lmin <= U && lmax >= L)29 ans += d[i];30 }31 else32 {33 lmin = ans;34 lmax = ans + d[i] -1;35 if (lmax < L || lmin > U)36 ans += d[i];37 }38 }39 printf("%lld\n", ans);40 }41 return 0;42 }
开始用位移操作,可是总是出现错误,应该是类型范围的问题吧,这方面很弱,感觉这些东西不怎么用,而且有点枯燥,就没怎么看过,即使看也是大概看看,没好好研究,还是要抽时间看一下的(话说,我现在感觉还是用的不多,不过,遇到问题就完蛋了...)