Description

  比特集合是一种抽象数据类型(Abstract Data Type) ,其包含一个集合S,并支持如下几种操作:
  INS M : 将元素 M 插入到集合S中;
  DEL M : 将集合S中所有等于 M 的元素删除;
  ADD M : 将集合S中的所有元素都增加数值M ;
  QBIT k : 查询集合中有多少个元素满足其二进制的第 k位为 1 。
  初始时,集合S为空集。请实现一个比特集合,并对于所有的QBIT操作输出相应的答案。

Input

  输入第一行包含一个正整数N,表示操作的数目。
  接下来N行,每行为一个操作,格式见问题描述。

Output

  对于每一个QBIT操作,输出一行,表示相应的答案。

Sample Input

8
INS 1
QBIT 0
ADD 1
QBIT 0
QBIT 1
DEL 2
INS 1
QBIT 1

Sample Output

1
0
1
0

HINT

数据规模和约定
时间限制2s。
对于30%的数据,1 ≤ N ≤ 10000。
对于100%的数据,1 ≤ N ≤ 500000;QBIT操作中的k满足, 0 ≤ k < 16。INS/DEL操作中,满足0 ≤ M ≤ 10^9;ADD操作中, 满足0 ≤ M ≤ 1000。
注意集合S可以包含多个重复元素。

正解:树状数组。

维护$16$个树状数组,其中第$i$个表示每个数$ \mod 2^{i+1}$的数是什么。

插入删除直接在树状数组里面搞就行了,查询某个数的个数直接$hash$就行了。

区间加就直接对于每个树状数组记录目前的$0$在哪个位置,不对树状数组进行修改。

查询就直接在$2^{k+1}$的树状数组上查询$[2^{k},2^{k+1}-1]$的数有多少个就行了。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define lb(x) (x & -x)
#define rhl (1253557) using namespace std; struct edge{ int nt,to,v; }g[]; int c[][],bin[],head[rhl+],n,m,num;
char ch[]; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG int from,RG int to,RG int v){
g[++num]=(edge){head[from],to,v},head[from]=num; return;
} il void add(RG int id,RG int x,RG int v){
for (;x<=bin[id+];x+=lb(x)) c[id][x]+=v; return;
} il int query(RG int id,RG int x){
RG int res=; for (;x;x-=lb(x)) res+=c[id][x]; return res;
} il void hshadd(RG int x,RG int v){
RG int wyh=(x%rhl+rhl)%rhl;
for (RG int i=head[wyh];i;i=g[i].nt)
if (g[i].to==x){ g[i].v+=v; return; }
insert(wyh,x,v); return;
} il int hshquery(RG int x){
RG int wyh=(x%rhl+rhl)%rhl;
for (RG int i=head[wyh];i;i=g[i].nt)
if (g[i].to==x) return g[i].v;
return ;
} int main(){
#ifndef ONLINE_JUDGE
freopen("bit.in","r",stdin);
freopen("bit.out","w",stdout);
#endif
n=gi(),bin[]=;
for (RG int i=;i<=;++i) bin[i]=bin[i-]<<;
for (RG int i=,x,k,l,r;i<=n;++i){
scanf("%s",ch);
if (ch[]=='I'){
x=gi();
for (RG int j=,y;j<=;++j){
y=(x-m)%bin[j+]; if (y<=) y+=bin[j+]; add(j,y,);
}
hshadd(x-m,);
}
if (ch[]=='D'){
x=gi(),k=hshquery(x-m); if (!k) continue;
for (RG int j=,y;j<=;++j){
y=(x-m)%bin[j+]; if (y<=) y+=bin[j+]; add(j,y,-k);
}
hshadd(x-m,-k);
}
if (ch[]=='A') m+=gi();
if (ch[]=='Q'){
k=gi(),l=(bin[k]-m)%bin[k+],r=(bin[k+]--m)%bin[k+];
if (l<=) l+=bin[k+]; if (r<=) r+=bin[k+];
if (l<=r) printf("%d\n",query(k,r)-query(k,l-));
else printf("%d\n",query(k,r)-query(k,l-)+query(k,bin[k+]));
}
}
return ;
}

bzoj2568 比特集合的更多相关文章

  1. BZOJ2568 比特集合(树状数组)

    考虑维护f[k][x]表示“最低k位所表示的数不大于x”的数的个数.那么查询时答案就为f[k][2k-1]-f[k][2k-1-1]. 同时记录每个数在集合中出现多少次.这样的话插入.删除已经解决了, ...

  2. BZOJ2568 [国家集训队2012]比特集合

    Description 比特集合是一种抽象数据类型(Abstract Data Type) ,其包含一个集合S,并支持如下几种操作: INS M : 将元素 M 插入到集合S中: DEL M : 将集 ...

  3. B2568 比特集合 树状数组

    啊啊啊,跳题坑死人.抽了一道国集的题,自己瞎编了一个算法,好像过不了而半途而废.转去看题解,发现用二维树状数组维护一下,偏移量我倒是想对了,但是维护的东西和我的完全不一样.还是有很大差距啊... 题解 ...

  4. BZOJ 2568 比特集合

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2568 题意:维护一个集合S,支持以下操作: (1)INS M : 将元素 M 插入 ...

  5. UML的概念模型

    为 了理解UML,需要形成该语言的概念模型,这要求学习建模的3个要素:UML的基本构造块.支配这些构造块如何放在一起的规则和一些运用于整个UML的公 共机制.如果掌握了这些思想,就能够读懂UML模型, ...

  6. 关联规则算法Apriori的学习与实现

    转自关联规则算法Apriori的学习与实现 首先我们来看,什么是规则?规则形如"如果-那么-(If-Then-)",前者为条件,后者为结果.关联规则挖掘用于寻找给定数据集中项之间的 ...

  7. 了解java虚拟机—垃圾回收算法(5)

    引用计数器法(Reference Counting) 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器减1.只要对象A的引用计数器的 ...

  8. OpenGL和D3D11中的深度模版测试

        在OpenGL和D3D11的管线中,像素shader之后的操作就是深度模版测试,深度模版测试是以sample为单位进行的,就是一个像素上可以有多个采样点,每个采样点都有深度信息.深度模版测试对 ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. java——线段树 SegmentTree

    应用: 区间染色 区间查询 线段树不是完全二叉树,线段树是平衡二叉树 使用数组来实现线段树:存储空间为4n 以下是使用数组实现的静态线段树: public class SegmentTree<E ...

  2. CEF和JS交互

    CefClient提供所有浏览器事件处理的接口,重写CefClient类中的方法处理浏览器事件:包括Browser的生命周期,右键菜单,对话框,状态通知显示,下载事件,拖曳事件,焦点事件,键盘事件,离 ...

  3. python17 多线程学习

    多线程 多任务可以由多进程完成,也可以由一个进程内的多线程完成. 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程. 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的 ...

  4. Silverlight 鼠标双击 事件

    Silverlight 双击事件例子 <UserControl x:Class="MouseDbClick.MainPage" xmlns="http://sche ...

  5. java多线程(二)

    线程的阻塞状态: 参考java多线程(一)多线程的生命周期图解,多线程的五种状态.     1.1 join(),如果在A线程体里面执行了B线程的join()方法,那么A线程阻塞,直到B线程生命周期结 ...

  6. android window(二)从getSystemService到WindowManagerGlobal

    在Activity调用getSystemService(WINDOW_SERVICE) 调用的是父类ContextThemeWrapper package android.view; public c ...

  7. Boxes in a Line UVA - 12657 (双向链表)

    题目链接:https://vjudge.net/problem/UVA-12657 题目大意:输入n,m  代表有n个盒子 每个盒子最开始按1~n排成一行  m个操作, 1 x y  :把盒子x放到y ...

  8. git使用笔记-日志

    1.查看函数的历史修改 git log -L :git_deflate_bound:zlib.c2.查看HEAD的所有记录 git reflog $ git reflog 1a410ef HEAD@{ ...

  9. Java基本语法_循环练习系列(二)——万年历

    写万年历大致可以分为以下几个步骤: 1.根据用户输入的年份判断该年是否是闰年. 2.根据用户输入的月份计算该月的天数. 3.计算输入的年份之前的总天数. 4.计算输入的月份之前的天数. 5.计算该月的 ...

  10. http学习总结及思考

    针对前面几章的学习,加上在学长的指导下,希望对前面知识进行简单总结. 1.在报文的7个方法中,最常用的是:Head和Post 响应头:If-Modified-Since HEAD -> 服务器返 ...