• [POI2014]KUR-Couriers


    题意

    给一个数列,每次询问一个区间内有没有一个数出现次数超过一半

    题解

    主席树,一个数出现次数>一半,这个区间内只有这一个数满足,那么主席树直接维护所有数的出现次数,直接在树上二分查询

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(500010), __(1e7);
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, p[_], id[_], len, rt[__], ls[__], rs[__], sz[__], cnt;
    
    IL void Build(RG int &x, RG int l, RG int r){
        x = ++cnt;
        if(l == r) return;
        RG int mid = (l + r) >> 1;
        Build(ls[x], l, mid); Build(rs[x], mid + 1, r);
    }
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int pos){
        sz[++cnt] = sz[x]; ls[cnt] = ls[x]; rs[cnt] = rs[x]; sz[x = cnt]++;
        if(l == r) return;
        RG int mid = (l + r) >> 1;
        if(pos <= mid)Modify(ls[x], l, mid, pos);
        else Modify(rs[x], mid + 1, r, pos);
    }
    
    IL int Query(RG int A, RG int B, RG int l, RG int r, RG int half){
        if(l == r) return l;
        RG int sum1 = sz[ls[B]] - sz[ls[A]], sum2 = sz[rs[B]] - sz[rs[A]], mid = (l + r) >> 1;
        if(sum1 > half) return Query(ls[A], ls[B], l, mid, half);
        if(sum2 > half) return Query(rs[A], rs[B], mid + 1, r, half);
        return 0;
    }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); m = Read();
        for(RG int i = 1; i <= n; i++) id[i] = p[i] = Read();
        sort(p + 1, p + n + 1); len = unique(p + 1, p + n + 1) - p - 1;
        Build(rt[0], 1, len);
        for(RG int i = 1; i <= n; i++){
            id[i] = lower_bound(p + 1, p + len + 1, id[i]) - p;
            rt[i] = rt[i - 1];
            Modify(rt[i], 1, len, id[i]);
        }
        for(RG int i = 1, l, r; i <= m; i++)
            l = Read(), r = Read(), printf("%d
    ", Query(rt[l - 1], rt[r], 1, len, (r - l + 1) >> 1));
        return 0;
    }
    
  • 相关阅读:
    python面试
    Python 3.x--使用re模块,实现计算器运算实例
    Python 3.x--模块导入
    Python 3.x--序列化及反序列化
    Python 3.x--装饰器
    Python 3.x--函数的参数问题
    Python 3.x--文件seek、tell的用法
    Python 3.x--字典循环
    Python3.x--文件读写与list
    Python简介
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206367.html
Copyright © 2020-2023  润新知