Swap all odd and even bits

本文介绍了一种高效的方法来交换整数中所有奇数位与偶数位的比特值。通过使用位操作,例如按位与和位移,可以实现这一目标。具体步骤包括获取所有奇数位和偶数位,然后分别对它们进行右移和左移操作,最后将这两个结果合并。

reference: 

http://www.geeksforgeeks.org/swap-all-odd-and-even-bits/


Problem Definition:

Given an unsigned integer, swap all odd bits with even bits. For example, if the given number is 23 (00010111), it should be converted to 43 (00101011). Every even position bit is swapped with adjacent bit on right side (even position bits are highlighted in binary representation of 23), and every odd position bit is swapped with adjacent on left side.


Solution:

Let the input number be x
1) Get all even bits of x by doing bitwise and of x with 0xAAAAAAAA.The number 0xAAAAAAAA is a 32 bit number with all even bits set as 1 and all odd bits as 0.
2) Get all odd bits of x by doing bitwise and of x with 0x55555555.The number 0x55555555 is a 32 bit number with all odd bits set as 1 and all even bits as 0.
3) Right shift all even bits.
4) Left shift all odd bits.
5) Combine new even and odd bits and return.


Code:

unsigned int swapBits(unsigned int x)
{
    // Get all even bits of x
    unsigned int even_bits = x & 0xAAAAAAAA; 

    // Get all odd bits of x
    unsigned int odd_bits  = x & 0×55555555; 

    even_bits >>= 1;  // Right shift even bits
    odd_bits <<= 1;   // Left shift odd bits

    return (even_bits | odd_bits); // Combine even and odd bits
}


# CF1479D Odd Mineral Resource ## 题目描述 In Homer's country, there are $ n $ cities numbered $ 1 $ to $ n $ and they form a tree. That is, there are $ (n-1) $ undirected roads between these $ n $ cities and every two cities can reach each other through these roads. Homer's country is an industrial country, and each of the $ n $ cities in it contains some mineral resource. The mineral resource of city $ i $ is labeled $ a_i $ . Homer is given the plans of the country in the following $ q $ years. The plan of the $ i $ -th year is described by four parameters $ u_i, v_i, l_i $ and $ r_i $ , and he is asked to find any mineral resource $ c_i $ such that the following two conditions hold: - mineral resource $ c_i $ appears an odd number of times between city $ u_i $ and city $ v_i $ ; and - $ l_i \leq c_i \leq r_i $ . As the best friend of Homer, he asks you for help. For every plan, find any such mineral resource $ c_i $ , or tell him that there doesn't exist one. ## 输入格式 The first line contains two integers $ n $ ( $ 1 \leq n \leq 3 \cdot 10^5 $ ) and $ q $ ( $ 1 \leq q \leq 3 \cdot 10^5 $ ), indicating the number of cities and the number of plans. The second line contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \leq a_i \leq n $ ). Then the $ i $ -th line of the following $ (n-1) $ lines contains two integers $ x_i $ and $ y_i $ ( $ 1 \leq x_i, y_i \leq n $ ) with $ x_i \neq y_i $ , indicating that there is a bidirectional road between city $ x_i $ and city $ y_i $ . It is guaranteed that the given roads form a tree. Then the $ i $ -th line of the following $ q $ lines contains four integers $ u_i $ , $ v_i $ , $ l_i $ , $ r_i $ ( $ 1 \leq u_i \leq n $ , $ 1 \leq v_i \leq n $ , $ 1 \leq l_i \leq r_i \leq n $ ), indicating the plan of the $ i $ -th year. ## 输出格式 Print $ q $ lines, the $ i $ -th of which contains an integer $ c_i $ such that - $ c_i = {-1} $ if there is no such mineral resource that meets the required condition; or - $ c_i $ is the label of the chosen mineral resource of the $ i $ -th year. The chosen mineral resource $ c_i $ should meet those conditions in the $ i $ -th year described above in the problem statement. If there are multiple choices of $ c_i $ , you can print any of them. ## 输入输出样例 #1 ### 输入 #1 ``` 6 8 3 2 1 3 1 3 1 2 1 3 2 4 2 5 4 6 3 5 1 1 3 5 1 3 3 5 1 3 1 1 2 2 1 1 3 3 1 4 1 5 1 6 1 3 1 6 1 3 ``` ### 输出 #1 ``` -1 2 3 -1 3 2 2 3 ``` ## 说明/提示 In the first three queries, there are four cities between city $ 3 $ and city $ 5 $ , which are city $ 1 $ , city $ 2 $ , city $ 3 $ and city $ 5 $ . The mineral resources appear in them are mineral resources $ 1 $ (appears in city $ 3 $ and city $ 5 $ ), $ 2 $ (appears in city $ 2 $ ) and $ 3 $ (appears in city $ 1 $ ). It is noted that - The first query is only to check whether mineral source $ 1 $ appears an odd number of times between city $ 3 $ and city $ 5 $ . The answer is no, because mineral source $ 1 $ appears twice (an even number of times) between city $ 3 $ and city $ 5 $ . - The second and the third queries are the same but they can choose different mineral resources. Both mineral resources $ 2 $ and $ 3 $ are available. 为什么WA了 ```cpp #include <bits/stdc++.h> using namespace std; const int BITS = 20; const int MAX_N = 4e5 + 50; const int BSIZE = 1; int n, m, tot, a[MAX_N]; int fa[MAX_N][BITS], dep[MAX_N]; int dfn[MAX_N], in[MAX_N], out[MAX_N]; vector<int> e[MAX_N]; int L[MAX_N], R[MAX_N], pos[MAX_N]; int cnt[MAX_N], sum[MAX_N], ans[MAX_N]; struct Query { int l, r, p, L, R, id; bool operator < (const Query& rhs) const { if (pos[l] != pos[rhs.l]) return pos[l] < pos[rhs.l]; return (pos[l] & 1) ? r < rhs.r : r > rhs.r; } } q[MAX_N]; void init() { int cnt = n / BSIZE; for (int i = 1; i <= cnt; i++) { L[i] = (i - 1) * BSIZE + 1; R[i] = i * BSIZE; } if (R[cnt] < n) { L[cnt + 1] = R[cnt] + 1; R[++cnt] = n; } for (int i = 1; i <= cnt; i++) fill(pos + L[i], pos + R[i] + 1, i); } void modify(int idx) { cout << "modify " << idx << '\n'; sum[pos[idx]] -= cnt[idx]; cnt[idx] ^= 1; sum[pos[idx]] += cnt[idx]; } int query(int lt, int rt) { int lp = pos[lt], rp = pos[rt]; if (lp == rp) { for (int i = lt; i <= rt; i++) if (cnt[i]) return i; } else { for (int i = lt; i <= R[lp]; i++) if (cnt[i]) return i; for (int i = lp + 1; i < rp; i++) if (sum[i]) for (int j = L[i]; j <= R[i]; j++) if (cnt[j]) return j; for (int i = L[rp]; i <= rt; i++) if (cnt[i]) return i; } return -1; } void dfs(int u, int father, int depth) { fa[u][0] = father, dep[u] = depth; for (int k = 1; k < BITS; k++) fa[u][k] = fa[fa[u][k - 1]][k - 1]; in[u] = ++tot, dfn[tot] = u; for (int v : e[u]) if (v != father) dfs(v, u, depth + 1); out[u] = ++tot, dfn[tot] = u; } int LCA(int x, int y) { if (dep[x] > dep[y]) swap(x, y); for (int k = BITS - 1; ~k; k--) if (dep[x] <= dep[fa[y][k]]) y = fa[y][k]; if (x == y) return x; for (int k = BITS - 1; ~k; k--) if (fa[x][k] != fa[y][k]) x = fa[x][k], y = fa[y][k]; return x; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1, u, v; i < n; i++) { cin >> u >> v; e[u].push_back(v); e[v].push_back(u); } dfs(1, 0, 1); for (int i = 1, u, v; i <= m; i++) { cin >> u >> v >> q[i].L >> q[i].R; q[i].id = i; if (in[u] > in[v]) swap(u, v); q[i].r = in[v]; int lca = LCA(u, v); if (lca == u) q[i].l = in[u], q[i].p = 0; else q[i].l = out[u], q[i].p = lca; } init(); sort(q + 1, q + m + 1); int l = 1, r = 0; for (int i = 1; i <= m; i++) { int ql = q[i].l, qr = q[i].r; while (l > ql) modify(a[dfn[--l]]); while (r < qr) modify(a[dfn[++r]]); while (l < ql) modify(a[dfn[l++]]); while (r > qr) modify(a[dfn[r--]]); if (q[i].p) modify(a[q[i].p]); cout << q[i].id << '\n'; ans[q[i].id] = query(q[i].L, q[i].R); if (q[i].p) modify(a[q[i].p]); } for (int i = 1; i <= n; i++) cout << ans[i] << '\n'; return 0; } ```
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值