zoukankan      html  css  js  c++  java
  • P4587 [FJOI2016]神秘数(主席树)

    题意:给出1e5个数 查询l,r区间内第一个不能被表示的数

       比如1,2,4可以用子集的和表示出[1,7] 所以第一个不能被表示的是8

    题解:先考虑暴力的做法 把这个区间内的数字按从小到大排序后

       从前往后扫 当前能表示出[1,x] 假设第i个数字y-1<=x 那么就可以表示[1,x+y]

       如果y > x + 1那么第一个不能表示出的数字就是x+1

      

       我们根据这个性质来想 假如当前区间能表示出[1,x] 我们计算这个区间内所有比x小的数的和tmp

       如果tmp>x 那么我们显然可以表示出[1,tmp] 反之x+1就是答案 直接退出就好

       然后就用主席树来做求和这个东西

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e9 + 5;
    const int MAXN = 1e5 + 5;
    int n, cnt;
    int sum[MAXN << 5];
    int ls[MAXN << 5], rs[MAXN << 5];
    int t[MAXN];
    
    int inser(int o, int l, int r, int pos, int val) {
        int rt = ++cnt;
        ls[rt] = ls[o], rs[rt] = rs[o], sum[rt] = sum[o] + val;
        int m = l + r >> 1;
        if(l < r)
        if(pos <= m)  ls[rt] = inser(ls[o], l, m, pos, val);
        else rs[rt] = inser(rs[o], m + 1, r, pos, val);
        return rt;
    }
    
    int query(int x, int y, int l, int r, int ql, int qr) {
        if(ql <= l && qr >= r) return sum[y] - sum[x];
        int m = l + r >> 1;
        int res = 0;
        if(ql <= m) res += query(ls[x], ls[y], l, m, ql, qr);
        if(qr > m) res += query(rs[x], rs[y], m + 1, r, ql, qr);
        return res;
    }
    
    int main() {
        cnt = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            int x; scanf("%d", &x);
            t[i] = inser(t[i - 1], 1, INF, x, x);
        }
    
        int T;
        scanf("%d", &T);
        while(T--) {
            int l, r;
            scanf("%d%d", &l, &r);
            int ans = 1;
            while(1) {
                int tmp = query(t[l - 1], t[r], 1, INF, 1, ans);
                if(tmp >= ans) ans = tmp + 1;
                else break;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    深入解析委托和事件
    一个小型工程报价系统(三层架构)
    DONET三层架构开发初步
    VS项目重命名工具
    Visual Studio 2012 应用软件开发新方式
    Consumer is not subscribed to any topics or assigned any partitions
    kafka的一些常用命令
    横向遍历二叉树
    Flume的断点续传解决
    实际生产用法CMS和G1
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11897977.html
Copyright © 2011-2022 走看看