树状数组 + 位运算 LA 4013 A Sequence of Numbers
生活随笔
收集整理的這篇文章主要介紹了
树状数组 + 位运算 LA 4013 A Sequence of Numbers
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
題目傳送門
題意:n個數(shù),兩種操作,一是每個數(shù)字加x,二是查詢& (1 << T) == 1 的個數(shù)
分析:因為累加是永遠的,所以可以離線處理。樹狀數(shù)組點是c[16][M] 表示數(shù)字x%(1 << j) 后的數(shù)字pos,考慮第j位的個數(shù)。當詢問時根據(jù)add不同的值不同的處理情況。
#include <bits/stdc++.h> using namespace std;typedef long long ll; const int N = 1e5 + 5; const int R = (int) 1 << 16; const int M = R + 10; struct BIT {int c[16][M];void init(void) {memset (c, 0, sizeof (c));}void updata(int b, int pos) {pos++; //pos 可能等于0while (pos < M) {c[b][pos] += 1;pos += pos & -pos;}}int sum(int b, int pos) {pos++;int ret = 0;while (pos > 0) {ret += c[b][pos];pos -= pos & -pos;}return ret;} }bit;int main(void) {int n, cas = 0;while (scanf ("%d", &n) == 1) {if (n == -1) break;bit.init ();for (int x, i=0; i<n; ++i) {scanf ("%d", &x);for (int j=0; j<16; ++j) {bit.updata (j, x % (1 << (j + 1)));}}ll add = 0, ans = 0; char str[2];while (scanf ("%s", &str) == 1) {if (str[0] == 'E') break;if (str[0] == 'C') { //離線int x; scanf ("%d", &x);add += x;if (add >= R) add %= R;}else {int t; scanf ("%d", &t);int tail = add % (1 << t);if (add & (1 << t)) { //(1<<t)位上已經(jīng)有1ans += bit.sum (t, (1 << t) - 1 - tail); //+tail 之前之后,都是0ans += bit.sum (t, (1 << (t + 1)) - 1) - bit.sum (t, (1 << (t + 1)) - 1 - tail); //+tail 之前1,之后0}else {ans += bit.sum (t, (1 << (t + 1)) - 1 - tail) - bit.sum (t, (1 << t) - 1 - tail); //+tail 之后1}}}printf ("Case %d: %lld\n", ++cas, ans);}return 0; }
?
轉(zhuǎn)載于:https://www.cnblogs.com/Running-Time/p/5221529.html
總結(jié)
以上是生活随笔為你收集整理的树状数组 + 位运算 LA 4013 A Sequence of Numbers的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python基础-C扩展
- 下一篇: 【Mac】tar 打包指定目录并排除某些