树状数组 + 位运算 LA 4013 A Sequence of Numbers

题目传送门

题意:n个数,两种操作,一是每个数字加x,二是查询& (1 << T) == 1 的个数

分析:因为累加是永远的,所以可以离线处理。树状数组点是c[16][M] 表示数字x%(1 << j) 后的数字pos,考虑第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 可能等于0
        while (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)位上已经有1
                    ans += bit.sum (t, (1 << t) - 1 - tail);        //+tail 之前之后,都是0
                    ans += 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;
}

  

时间: 2024-11-23 11:58:34

树状数组 + 位运算 LA 4013 A Sequence of Numbers的相关文章

LA 4329 (树状数组) Ping pong

第一次写树状数组,感觉那个lowbit位运算用的相当厉害. 因为-x相当于把x的二进制位取反然后整体再加上1,所以最右边的一个1以及末尾的0,取反加一以后不变. 比如1000取反是0111加一得到1000,这样与运算以后不变 最右边的1左边部分取反,加一不会影响左半部分,所以与运算以后全部为0 对于这道题来说貌似不是很容易能联想到树状数组 注意题中说了每个人的技能值互不相同. 从左往右扫描每个a[i],另x[a[i]] = 1,然后统计x[1]...x[a[i]-1]的和就是第i个人左边技能值比

树状数组 LA 4329 亚洲赛北京赛区题

复习下树状数组 还是蛮有意思的一道题: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=501&page=show_problem&problem=4174 学到几点: 1.树状数组C[i]的构建,一则c[i]=s[i]-s[i-lowbit(i)];这是一直用的做法.如今学到一种新的,直接add(i,a[i]),(s[i]为a[1]到a[i]的和) 2.前缀和思想,

LA 4329(树状数组)

题目描述: N <tex2html_verbatim_mark>(3N20000) <tex2html_verbatim_mark>ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To improve their skill rank, they often compete with

LA 4329(树状数组)

算法竞赛入门经典 p197 题目大意: 一条大街上住着n个乒乓球爱好者.常常比赛切磋技术.每一个人都有一个不同的技能值a[i].每场比赛须要3个人:两名选手,一名裁判.他们有个奇怪的约定,裁判必须住在两名选手之间,而裁判的能力值也必须在两名选手之间.问一共能组织多少种比赛. 分析:    如果a[1]到a[i-1]中小于a[i]的数有p[i].a[i+1]到a[n]中小于a[i]的数有s[i]个; 这样当i为裁判时可以组织的比赛数目为:p[i]*(n-i-s[i]) + (i-1-p[i])*s

深入理解树状数组

树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询). 百度上给出了令人难以理解的概念,其实这个东西我也是琢磨了一天,参考了大量博客的笔记才搞清楚了大致思路和原理,说说心得吧! 假设数组a[1..n],那么

【转】树状数组

转自:http://blog.csdn.net/int64ago/article/details/7429868 一.树状数组是干什么的? 平常我们会遇到一些对数组进行维护查询的操作,比较常见的如,修改某点的值.求某个区间的和,而这两种恰恰是树状数组的强项!当然,数据规模不大的时候,对于修改某点的值是非常容易的,复杂度是O(1),但是对于求一个区间的和就要扫一遍了,复杂度是O(N),如果实时的对数组进行M次修改或求和,最坏的情况下复杂度是O(M*N),当规模增大后这是划不来的!而树状数组干同样的

树状数组--转载

转自:http://blog.csdn.net/int64ago/article/details/7429868 写下这个标题,其实心里还是没底的,与其说是写博帖,不如说是做总结.第一个接触树状数组还是两年前,用什么语言来形容当时的感觉呢?--太神奇了!真的,无法表达出那种感觉,她是那么的优雅,10行不到的代码,却把事情干的如此出色!没有了解她原理的前提下即使把代码倒背如流也理解不了!其中,我就是一直没搞懂地在使用她.时隔两年,又无意遇到了她,可能是两年的代码经验的积累,有了些新的认识,可以自信

小白初理解树状数组

ACM的在线测试里经常涉及到大量数据的的修改,求和等操作,这里介绍一种方法——树状数组. 树状数组,是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值.可以用一张图来弄懂什么是数组数组. 原数组A[n],树状数组C[n]; 如果n为奇数:Cn=An; 如果n为偶数:Cn = A(n – 2^k + 1) + ... + An,k为n的二进制数

tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着身体. 描述 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵.第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作.第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作.第