zoukankan      html  css  js  c++  java
  • LOJ#2302 整数

    解:发现这苟东西是个3千万位的二进制数......毒瘤吧。

    拆位考虑,如果一个地方本来是1然后+1,就会把它和它前面连续的一段1变成0,并把第一个0变成1。

    如果本来是0然后-1了,就会把它和它前面连续的一段0变成1,并把第一个1变成0。

    然后发现这两个操作都可以用线段树。于是得到了一个60分算法。

    然后压位,线段树每一位表示30个二进制位,可以发现之前的性质没变:如果一个地方加了后超过了(1<<30)-1,就把前面的一段1变成0,第一个0变成1。减法同理。

    注意加法爆了就对(1<<30)-1取&,减法爆了就加上(1<<30),这里千万不能-1,因为是从前面借的。

    有个地方坑死我了......看这里。

    应该长这样...

      1 #include <bits/stdc++.h>
      2 
      3 inline void read(int &x) {
      4     x = 0;
      5     char c = getchar();
      6     bool f = 0;
      7     while(c < '0' || c > '9') {
      8         if(c == '-') f = 1;
      9         c = getchar();
     10     }
     11     while(c >= '0' && c <= '9') {
     12         x = x * 10 + c - 48;
     13         c = getchar();
     14     }
     15     if(f) x = (~x) + 1;
     16     return;
     17 }
     18 
     19 const int N = 4000010, FULL = (1 << 30) - 1;
     20 
     21 inline void out(int x) {
     22     for(int i = 0; i <= 29; i++) printf("%d", (x >> i) & 1);
     23     return;
     24 }
     25 
     26 int n, tag[N], val[N], sta[N], lm;
     27 /// tag  is_same  now_state
     28 
     29 inline void pushup(int o) {
     30     if(val[o << 1] == val[o << 1 | 1] && val[o << 1] != -1) {
     31         val[o] = val[o << 1];
     32     }
     33     else val[o] = -1;
     34     return;
     35 }
     36 
     37 inline void pushdown(int o) {
     38     if(tag[o] != -1) {
     39         tag[o << 1] = tag[o << 1 | 1] = tag[o];
     40         val[o << 1] = val[o << 1 | 1] = tag[o];
     41         sta[o << 1] = sta[o << 1 | 1] = (tag[o] ? FULL : 0);
     42         tag[o] = -1;
     43     }
     44     return;
     45 }
     46 
     47 void changeAdd(int l, int r, int o) {
     48     if(l == r) {
     49         for(int i = 0; i < 30; i++) {
     50             if(((sta[o] >> i) & 1) == 0) {
     51                 sta[o] |= (1 << i);
     52                 break;
     53             }
     54             else {
     55                 sta[o] &= ~(1 << i);
     56             }
     57         }
     58         if(sta[o] == FULL) val[o] = 1;
     59         else if(sta[o] == 0) val[o] = 0;
     60         else val[o] = -1;
     61         return;
     62     }
     63     int mid = (l + r) >> 1;
     64     pushdown(o);
     65     if(val[o << 1] != 1) {
     66         changeAdd(l, mid, o << 1);
     67     }
     68     else {
     69         changeAdd(mid + 1, r, o << 1 | 1);
     70         sta[o << 1] = val[o << 1] = tag[o << 1] = 0;
     71     }
     72     pushup(o);
     73     return;
     74 }
     75 
     76 void changeDel(int l, int r, int o) {
     77     if(l == r) {
     78         for(int i = 0; i < 30; i++) {
     79             if((sta[o] >> i) & 1) {
     80                 sta[o] &= ~(1 << i);
     81                 break;
     82             }
     83             else {
     84                 sta[o] |= (1 << i);
     85             }
     86         }
     87         if(sta[o] == FULL) val[o] = 1;
     88         else if(sta[o] == 0) val[o] = 0;
     89         else val[o] = -1;
     90         return;
     91     }
     92     int mid = (l + r) >> 1;
     93     pushdown(o);
     94     if(val[o << 1] != 0) {
     95         changeDel(l, mid, o << 1);
     96     }
     97     else {
     98         changeDel(mid + 1, r, o << 1 | 1);
     99         val[o << 1] = tag[o << 1] = 1;
    100         sta[o << 1] = FULL;
    101     }
    102     pushup(o);
    103     return;
    104 }
    105 
    106 int add(int p, int v, int l, int r, int o) {
    107     if(l == r) {
    108         sta[o] += v;
    109         int t = 0;
    110         if(sta[o] > FULL) {
    111             sta[o] &= FULL;
    112             t = 1;
    113         }
    114         if(sta[o] == FULL) val[o] = 1;
    115         else if(sta[o] == 0) val[o] = 0;
    116         else val[o] = -1;
    117         return t;
    118     }
    119     int mid = (l + r) >> 1;
    120     pushdown(o);
    121     int t;
    122     if(p <= mid) {
    123         t = add(p, v, l, mid, o << 1);
    124         pushup(o);
    125         if(t && val[o << 1 | 1] != 1) {
    126             changeAdd(mid + 1, r, o << 1 | 1);
    127             pushup(o);
    128             return 0;
    129         }
    130         else if(t) {
    131             tag[o << 1 | 1] = val[o << 1 | 1] = sta[o << 1 | 1] = 0;
    132             pushup(o);
    133             return 1;
    134         }
    135         else return 0;
    136     }
    137     else {
    138         t = add(p, v, mid + 1, r, o << 1 | 1);
    139         pushup(o);
    140         return t;
    141     }
    142     return 0;
    143 }
    144 
    145 int del(int p, int v, int l, int r, int o) {
    146     if(l == r) {
    147         sta[o] -= v;
    148         int t = 0;
    149         if(sta[o] < 0) {
    150             sta[o] += FULL + 1;
    151             t = 1;
    152         }
    153         if(sta[o] == FULL) val[o] = 1;
    154         else if(sta[o] == 0) val[o] = 0;
    155         else val[o] = -1;
    156         return t;
    157     }
    158     int mid = (l + r) >> 1;
    159     pushdown(o);
    160     int t;
    161     if(p <= mid) {
    162         t = del(p, v, l, mid, o << 1);
    163         pushup(o);
    164         if(t && val[o << 1 | 1] != 0) {
    165             changeDel(mid + 1, r, o << 1 | 1);
    166             pushup(o);
    167             return 0;
    168         }
    169         else if(t) {
    170             tag[o << 1 | 1] = val[o << 1 | 1] = 1;
    171             sta[o << 1 | 1] = FULL;
    172             pushup(o);
    173             return 1;
    174         }
    175         else return 0;
    176     }
    177     else {
    178         t = del(p, v, mid + 1, r, o << 1 | 1);
    179         pushup(o);
    180         return t;
    181     }
    182     return 0;
    183 }
    184 
    185 inline void Add(int p, int x) { /// node p add x
    186     if(!x) return;
    187     add(p, x, 1, lm, 1);
    188     return;
    189 }
    190 
    191 inline void Del(int p, int x) {
    192     if(!x) return;
    193     del(p, x, 1, lm, 1);
    194     return;
    195 }
    196 
    197 int ask(int p, int l, int r, int o) {
    198     if(l == r) {
    199         p -= (l - 1) * 30;
    200         return (sta[o] >> p) & 1;
    201     }
    202     int mid = (l + r) >> 1;
    203     pushdown(o);
    204     if(p <= mid * 30 - 1) return ask(p, l, mid, o << 1);
    205     else return ask(p, mid + 1, r, o << 1 | 1);
    206 }
    207 
    208 void out(int l, int r, int o) {
    209     if(l == r) {
    210         return;
    211     }
    212     int mid = (l + r) >> 1;
    213     pushdown(o);
    214     out(l, mid, o << 1);
    215     out(mid + 1, r, o << 1 | 1);
    216     return;
    217 }
    218 
    219 int main() {
    220     int t1, t2, t3;
    221     memset(tag, -1, sizeof(tag));
    222     scanf("%d%d%d%d", &n, &t1, &t2, &t3);
    223     lm = std::max(n + 10, 200);
    224     for(int i = 1, f, x, y; i <= n; i++) {
    225         scanf("%d%d", &f, &x);
    226         if(f == 2) {
    227             printf("%d
    ", ask(x, 1, lm, 1));
    228         }
    229         else {
    230             scanf("%d", &y);
    231             int t, fd = 0;
    232             if(x < 0) {
    233                 x = -x;
    234                 fd = 1;
    235             }
    236             if(!fd) { /// add
    237                 t = (x << (y % 30)) & FULL;
    238                 Add(y / 30 + 1, t);
    239                 t = x >> (30 - (y % 30));
    240                 Add(y / 30 + 2, t);
    241             }
    242             else { /// dec
    243                 t = (x << (y % 30)) & FULL;
    244                 Del(y / 30 + 1, t);
    245                 t = x >> (30 - (y % 30));
    246                 Del(y / 30 + 2, t);
    247             }
    248         }
    249     }
    250     return 0;
    251 }
    AC代码
  • 相关阅读:
    Timer类的常见使用方法
    转:HTTP协议简介
    DS-5新加交叉编译工具
    C++的引用
    C++构造函数的几种使用方法
    Eclipse 快捷键
    eclipse Outline里图标的含义
    Linux 内存映射函数 mmap()函数详解
    Sockit 硬件接口编程——点亮一个LED
    更新Preloader与uboot
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10542603.html
Copyright © 2011-2022 走看看