• [NOI 2017]整数


    Description

    题库链接

    P 博士将他的计算任务抽象为对一个整数的操作。

    具体来说,有一个整数 (x) ,一开始为 (0)

    接下来有 (n) 个操作,每个操作都是以下两种类型中的一种:

    • 1 a b :将 (x) 加上整数 (acdot 2^b) ,其中 (a) 为一个整数, (b) 为一个非负整数
    • 2 k :询问 (x) 在用二进制表示时,位权为 (2^k) 的位的值(即这一位上的 (1) 代表 (2^k)

    保证在任何时候, (xgeqslant 0)

    (1leq nleq 10^6,|a| leq 10^9,0 leq b, k leq 30n)

    Solution

    考虑稍微暴力一点的做法,我们开两个数组来模拟进位(一个是 (a > 0) ,另一个 (a < 0) )。

    然后对于询问,我们假设小于 (k) 位的部分 (a>0) 的是 (s_1)(a<0) 的是 (s_2)

    讨论所有情况,我们可以得出结论:

    • (s_1geq s2) ,输出答案为 ([xoplus y]) ,其中 (x)(a>0) 的第 (k) 位的值, (y)(a<0) 的第 (k) 位的值。
    • (s_1< s2) ,输出答案为 ([x=y])

    这样总复杂度是 (O(30nlog(30n))) 的。

    考虑优化。

    直接拿 ( ext{zkw线段树}) 卡过去啦!

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int M = 1000000*30+300;
    void gi(int &x) {
        char ch = getchar(); x = 0; int flag = 0;
        for (; ch < '0' || ch > '9'; ch = getchar()) flag |= (ch == '-');
        for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x<<1)+(x<<3)+ch-48;
        if (flag) x = -x;
    }
    
    int s1[M], s2[M], tr[(1<<26)+5];
    int n, N, rbsc, opt, a, b, lst[32], bin[32], tot;
    
    void modify(int *s, int a, int b) {
        tot = 0;
        for (int i = 30; i >= 0 && a; i--)
            if (bin[i]&a) lst[++tot] = i, a -= bin[i];
        int r = lst[1]+b, l = lst[tot]+b;
        for (int i = 1; i <= tot; i++) {
            int loc = lst[i]+b;
            while (s[loc]) s[loc++] = 0;
            r = max(r, loc), s[loc] = 1;
        }
        for (int i = l; i <= r; i++) tr[N+i] = (s1[i]^s2[i]);
        for (l = (l+N)>>1, r = (r+N)>>1; l; l >>= 1, r >>= 1)
            for (int j = l; j <= r; j++) tr[j] = tr[j<<1]|tr[j<<1|1];
    }
    int query(int a) {
        for (a += N; a; a >>= 1)
            if (a&1&tr[a^1]) {
                for (a ^= 1; a < N; a = a<<1|tr[a<<1|1]);
                return a-N;
            }
        return -1;
    }
    void work() {
        gi(n); gi(rbsc), gi(rbsc), gi(rbsc);
        for (N = 1; N <= n*30; N <<= 1);
        bin[0] = 1; for (int i = 1; i <= 30; i++) bin[i] = (bin[i-1]<<1);
        while (n--) {
            gi(opt);
            if (opt == 1) {
                gi(a), gi(b);
                if (a < 0) modify(s2, -a, b);
                else modify(s1, a, b);
            }else {
                gi(a); int now = query(a);
                if (now == -1 || s1[now] > s2[now]) putchar('0'+(s1[a]^s2[a]));
                else putchar('0'+(s1[a] == s2[a]));
                putchar('
    ');
            }
        }
    }
    int main() {work(); return 0; }
  • 相关阅读:
    数据库中Schema(模式)概念的理解
    debug --- 使用Eclipse
    pgsql 相关函数
    浏览器显示页面排版错误
    jqury 属性
    节点互换需要克隆
    mysql数据库允许远程访问
    request与response的编码和解码
    文本和属性 radio,checkbox,select
    js 和 JQuery 获取iframe的父子值
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/9290018.html
Copyright © 2020-2023  润新知