zoukankan      html  css  js  c++  java
  • LOJ#2302. 「NOI2017」整数

    $n leq 1000000$个操作:一,给$x$加上$a*2^b$;二,问$x$的某个二进制位$k$。$b,k leq 30n$,$|a| leq 1e9$。

    30暴露了一切。。可以把30个二进制位压一位,进位用线段树找到第一个0,而退位用类似的方法找到第一个1。

    但其实第$k$位只由加的总量和减的总量的0到$k$这些数位上决定。因此可以把加减分成两个数组,不用再写一个线段树里的减法。回答时查一下$0$到$k-1$中加的和减的孰大孰小,以及第$k$位是否相同,分类可得答案。

    这里写的直接模拟。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<math.h>
      5 //#include<set>
      6 //#include<queue>
      7 //#include<bitset>
      8 //#include<vector>
      9 #include<algorithm>
     10 #include<stdlib.h>
     11 using namespace std;
     12 
     13 #define LL long long
     14 int qread()
     15 {
     16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     18 }
     19 
     20 //Pay attention to '-' , LL and double of qread!!!!
     21 
     22 int m,n;
     23 #define maxn 1000011
     24 int pos[maxn];
     25 struct SMT
     26 {
     27     struct Node{int ls,rs,v; bool all0,all1,be0,be1;}a[maxn<<1];
     28     int size,n;
     29     void up(int x)
     30     {a[x].all0=a[a[x].ls].all0&a[a[x].rs].all0; a[x].all1=a[a[x].ls].all1&a[a[x].rs].all1;}
     31     void build(int &x,int L,int R)
     32     {
     33         x=++size;
     34         a[x].all0=1; a[x].all1=a[x].be0=a[x].be1=0;
     35         if (L==R) {a[x].v=0; pos[L]=x; return;}
     36         int mid=(L+R)>>1;
     37         build(a[x].ls,L,mid); build(a[x].rs,mid+1,R);
     38     }
     39     void clear(int N) {n=N; size=0; int x; build(x,1,n);}
     40     
     41     void besingle(int x,bool t)
     42     {
     43         a[x].all0=a[x].be0=!t;
     44         a[x].all1=a[x].be1=t;
     45         if (t) a[x].v=(1<<30)-1; else a[x].v=0;
     46     }
     47     void down(int x)
     48     {
     49         Node &b=a[x];
     50         if (b.be0) {besingle(b.ls,0); besingle(b.rs,0); b.be0=0;}
     51         if (b.be1) {besingle(b.ls,1); besingle(b.rs,1); b.be1=0;}
     52     }
     53     
     54     bool Add(int x,int L,int R,int p,int v)
     55     {
     56         if (L==R)
     57         {
     58             a[x].v+=v; if (a[x].v>=(1<<30))
     59             {
     60                 a[x].v^=(1<<30);
     61                 a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
     62                 return 1;
     63             }
     64             a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
     65             return 0;
     66         }
     67         down(x);
     68         int mid=(L+R)>>1;
     69         if (p<=mid) {bool flag=Add(a[x].ls,L,mid,p,v); up(x); return flag;}
     70         bool flag=Add(a[x].rs,mid+1,R,p,v); up(x); return flag;
     71     }
     72     bool f0(int x,int L,int R,int p)
     73     {
     74         if (L==R)
     75         {
     76             bool flag=0;
     77             for (int i=0;i<30;i++) if (((a[x].v>>i)&1)==0) {a[x].v|=1<<i; flag=1; break;}
     78             else a[x].v^=(1<<i);
     79             a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
     80             return flag;
     81         }
     82         down(x);
     83         int mid=(L+R)>>1;
     84         if (L>p)
     85         {
     86             if (a[x].all1) {besingle(x,0); return 0;}
     87             if (!f0(a[x].ls,L,mid,p)) f0(a[x].rs,mid+1,R,p); up(x);
     88             return 1;
     89         }
     90         if (mid>p)
     91         {
     92             if (f0(a[x].ls,L,mid,p)) {up(x); return 1;}
     93             bool flag=f0(a[x].rs,mid+1,R,p); up(x); return flag;
     94         }
     95         if (f0(a[x].rs,mid+1,R,p)) {up(x); return 1;}
     96         up(x); return 0;
     97     }
     98     void add(int p,int v) {p++; if (Add(1,1,n,p,v) && p!=n) f0(1,1,n,p);}
     99     
    100     bool Minus(int x,int L,int R,int p,int v)
    101     {
    102         if (L==R)
    103         {
    104             a[x].v-=v; if (a[x].v<0)
    105             {
    106                 a[x].v+=(1<<30);
    107                 a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
    108                 return 1;
    109             }
    110             a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
    111             return 0;
    112         }
    113         down(x);
    114         int mid=(L+R)>>1;
    115         if (p<=mid) {bool flag=Minus(a[x].ls,L,mid,p,v); up(x); return flag;}
    116         bool flag=Minus(a[x].rs,mid+1,R,p,v); up(x); return flag;
    117     }
    118     bool f1(int x,int L,int R,int p)
    119     {
    120         if (L==R)
    121         {
    122             bool flag=0;
    123             for (int i=0;i<30;i++) if (((a[x].v>>i)&1)==1) {a[x].v^=1<<i; flag=1; break;}
    124             else a[x].v^=(1<<i);
    125             a[x].all0=(a[x].v==0),a[x].all1=(a[x].v==(1<<30)-1);
    126             return flag;
    127         }
    128         down(x);
    129         int mid=(L+R)>>1;
    130         if (L>p)
    131         {
    132             if (a[x].all0) {besingle(x,1); return 0;}
    133             if (!f1(a[x].ls,L,mid,p)) f1(a[x].rs,mid+1,R,p);
    134             up(x); return 1;
    135         }
    136         if (mid>p)
    137         {
    138             if (f1(a[x].ls,L,mid,p)) {up(x); return 1;}
    139             bool flag=f1(a[x].rs,mid+1,R,p); up(x); return flag;
    140         }
    141         if (f1(a[x].rs,mid+1,R,p)) {up(x); return 1;}
    142         up(x); return 0;
    143     }
    144     void minus(int p,int v) {p++; if (Minus(1,1,n,p,v) && p!=n) f1(1,1,n,p);}
    145     
    146     int Query(int x,int L,int R,int p,int v)
    147     {
    148         if (L==R) return (a[x].v>>v)&1;
    149         down(x);
    150         int mid=(L+R)>>1;
    151         if (p<=mid) return Query(a[x].ls,L,mid,p,v);
    152         return Query(a[x].rs,mid+1,R,p,v);
    153     }
    154     int query(int x) {return Query(1,1,n,x/30+1,x%30);}
    155 }t;
    156 
    157 int main()
    158 {
    159     m=qread(); n=qread(); n=qread(); n=qread();
    160     n=1000000;
    161     t.clear(n);
    162     
    163     int op,x,y;
    164     while (m--)
    165     {
    166         op=qread();
    167         if (op==1)
    168         {
    169             x=qread(); y=qread();
    170             if (x>0)
    171             {
    172                 int p=y/30,q=(p+1)*30-y;
    173                 int a=x&((1<<q)-1),b=x>>q; a<<=y-p*30;
    174                 t.add(p,a); if (b) t.add(p+1,b);
    175             }
    176             else
    177             {
    178                 x=-x;
    179                 int p=y/30,q=(p+1)*30-y;
    180                 int a=x&((1<<q)-1),b=x>>q; a<<=y-p*30;
    181                 t.minus(p,a); if (b) t.minus(p+1,b);
    182             }
    183         }
    184         else
    185         {
    186             x=qread();
    187             printf("%d
    ",t.query(x));
    188         }
    189     }
    190     return 0;
    191 }
    View Code
  • 相关阅读:
    【甘道夫】通过Mahout构建贝叶斯文本分类器案例具体解释
    hdu 5044 树区间操作最后输出/ lca+dfs
    UVA 1371
    裴蜀定理
    iOS 开发系列:CoreData Object 变成 Fault 的一种方式
    UVa 10633
    校赛热身赛 Problem D. Unsolved Mystery
    校赛热身赛 Problem D. Unsolved Mystery
    NOIP2005普及组第4题 循环
    NOIP2005普及组第4题 循环
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9205442.html
Copyright © 2011-2022 走看看