• bzoj2568 比特集合


    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]$的数有多少个就行了。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define lb(x) (x & -x)
     6 #define rhl (1253557)
     7  
     8 using namespace std;
     9  
    10 struct edge{ int nt,to,v; }g[1000010];
    11  
    12 int c[17][150010],bin[17],head[rhl+10],n,m,num;
    13 char ch[5];
    14  
    15 il int gi(){
    16   RG int x=0,q=1; RG char ch=getchar();
    17   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    18   if (ch=='-') q=-1,ch=getchar();
    19   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    20   return q*x;
    21 }
    22  
    23 il void insert(RG int from,RG int to,RG int v){
    24   g[++num]=(edge){head[from],to,v},head[from]=num; return;
    25 }
    26  
    27 il void add(RG int id,RG int x,RG int v){
    28   for (;x<=bin[id+1];x+=lb(x)) c[id][x]+=v; return;
    29 }
    30  
    31 il int query(RG int id,RG int x){
    32   RG int res=0; for (;x;x-=lb(x)) res+=c[id][x]; return res;
    33 }
    34  
    35 il void hshadd(RG int x,RG int v){
    36   RG int wyh=(x%rhl+rhl)%rhl;
    37   for (RG int i=head[wyh];i;i=g[i].nt)
    38     if (g[i].to==x){ g[i].v+=v; return; }
    39   insert(wyh,x,v); return;
    40 }
    41  
    42 il int hshquery(RG int x){
    43   RG int wyh=(x%rhl+rhl)%rhl;
    44   for (RG int i=head[wyh];i;i=g[i].nt)
    45     if (g[i].to==x) return g[i].v;
    46   return 0;
    47 }
    48  
    49 int main(){
    50 #ifndef ONLINE_JUDGE
    51   freopen("bit.in","r",stdin);
    52   freopen("bit.out","w",stdout);
    53 #endif
    54   n=gi(),bin[0]=1;
    55   for (RG int i=1;i<=16;++i) bin[i]=bin[i-1]<<1;
    56   for (RG int i=1,x,k,l,r;i<=n;++i){
    57     scanf("%s",ch);
    58     if (ch[0]=='I'){
    59       x=gi();
    60       for (RG int j=0,y;j<=15;++j){
    61     y=(x-m)%bin[j+1]; if (y<=0) y+=bin[j+1]; add(j,y,1);
    62       }
    63       hshadd(x-m,1);
    64     }
    65     if (ch[0]=='D'){
    66       x=gi(),k=hshquery(x-m); if (!k) continue;
    67       for (RG int j=0,y;j<=15;++j){
    68     y=(x-m)%bin[j+1]; if (y<=0) y+=bin[j+1]; add(j,y,-k);
    69       }
    70       hshadd(x-m,-k);
    71     }
    72     if (ch[0]=='A') m+=gi();
    73     if (ch[0]=='Q'){
    74       k=gi(),l=(bin[k]-m)%bin[k+1],r=(bin[k+1]-1-m)%bin[k+1];
    75       if (l<=0) l+=bin[k+1]; if (r<=0) r+=bin[k+1];
    76       if (l<=r) printf("%d
    ",query(k,r)-query(k,l-1));
    77       else printf("%d
    ",query(k,r)-query(k,l-1)+query(k,bin[k+1]));
    78     }
    79   }
    80   return 0;
    81 }
  • 相关阅读:
    OC面向对象—封装
    设计模式之类关系
    理性:中国别一厢情愿救俄罗斯(转)
    Mockito--完整功能介绍(转)
    从陌陌上市看BAT的移动保卫战(转)
    This exception may occur if matchers are combined with raw values
    RepositoryClassLoader.java
    搭建你的持续集成server
    mysql中怎样查看和删除唯一索引
    Android中Context具体解释 ---- 你所不知道的Context
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7470238.html
Copyright © 2020-2023  润新知