zoukankan      html  css  js  c++  java
  • HDU6703 array (线段树)

    题意:长为1e5的全排列 有两个操作 把一个数删掉

       询问1,r这个区间内 找到一个数大于等于x 且这个数不等于区间内的所有数

    题解:建一颗权值线段树 线段树里存值为i的数在原数组中的坐标 维护坐标的最大值

       考虑删除操作 就等于让他的坐标变为n+1 因为答案一定在1-n+1

       对于查询操作 等价于找在[x,n]这个权值区间内左边第一个出现的数 且他的坐标是大于r的

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 5;
    
    int n, m;
    int a[MAXN], b[MAXN];
    int pos[MAXN << 2];
    
    void pushup(int rt) {
        pos[rt] = max(pos[rt << 1], pos[rt << 1 | 1]);
    }
    
    void build(int l, int r, int rt) {
        if(l == r) {
            pos[rt] = b[l];
            return;
        }
    
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    void update(int k, int l, int r, int rt) {
        if(l == r) {
            pos[rt] = n + 1;
            return;
        }
    
        int mid = l + r >> 1;
        if(k <= mid) update(k, l, mid, rt << 1);
        else update(k, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    int query(int ql, int qr, int k, int l, int r, int rt) {
        int mid = l + r >> 1;
        if(ql <= l && qr >= r) {
            if(l == r) {
                if(pos[rt] > k) return l;
                else return n + 1;
            }
    
            if(pos[rt << 1] > k) return query(ql, qr, k, l, mid, rt << 1);
            if(pos[rt << 1 | 1] > k) return query(ql, qr, k, mid + 1, r, rt << 1 | 1);
            return n + 1;
        }
    
        if(qr <= mid) return query(ql, qr, k, l, mid, rt << 1);
        if(ql > mid) return query(ql, qr, k, mid + 1, r, rt << 1 | 1);
        return min(query(ql, qr, k, l, mid, rt << 1), query(ql, qr, k, mid + 1, r, rt << 1 | 1));
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            int las = 0;
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[a[i]] = i;
            build(1, n, 1);
            for(int i = 1; i <= m; i++) {
                int opt, x, y;
                scanf("%d%d", &opt, &x); x ^= las;
                if(opt == 1) update(a[x], 1, n, 1);
                else {
                    scanf("%d", &y); y ^= las;
                    printf("%d
    ", las = query(y, n, x, 1, n, 1));
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    元祖操作
    列表操作
    字符串操作
    zabbix监控脚本
    nginx 使用php-fpm的配置php环境参数
    网卡切换脚本
    mysql数据备份脚本
    docker概念
    网络链路质量监控smokeping
    搭建speedtest
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11541455.html
Copyright © 2011-2022 走看看