zoukankan      html  css  js  c++  java
  • [POI2014]KUR-Couriers

    这个题……一开始在挂……(ORZ)最终发现是我的主席树挂了……看来我该退役了(OTZ)

    #(mathcal{color{red}{Description}})

    (color{cyan}{mathcal{Link}})

    给一个数列,每次询问一个区间内有没有一个数出现次数超过一半。如果有的话,输出这个数的数值。

    #(mathcal{color{red}{Solution}})

    这个题好像可以上莫队……但是我校大佬讲莫队的时候没有用心听(ORZ.)

    于是我们考虑用主席树(qwq) ,而在这里我们千万不要忘了主席树的最基本的功能是,维护一段区间内某个数字的个数

    那我们就可以考虑,对于一个区间(L) ~ (R),我们取树(R)和树(L - 1)作差得到树(W),之后在(W)(1)~(Len)里面递归下去,递归的选择是某个区间的元素个数比区间内元素个数的二分之一要大。假设(l)区间内的元素数量比((qr - ql + 1 )/2)要大,那么首先对于区间(r)来说,(r)肯定不合法,所以向(l)区间继续递归下去。如果递归时出现左右区间都不满足,那么直接(return) (0.)

    il int query(int Left, int Right, int l, int r, int k){
        if (l == r) return l ;
        int x = sum[L[Right]] - sum[L[Left]], y = sum[R[Right]] - sum[R[Left]] ;
        if ((x << 1) > k) return query(L[Left], L[Right], l, mid, k) ;
        if((y << 1) > k) return query(R[Left], R[Right], mid + 1, r, k) ;
        return 0 ;
    }
    

    嗯,其实只要明白了主席树的原理,这个题其实是很水的板子。不过像我这种蒟蒻因为入门的时候学的是区间第(k)小,所以忘记了主席树的基本功能……

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define il inline
    #define MAXN 500510
    #define mid ((l + r) >> 1)
    
    using namespace std ;
    int a, b, c ;
    int pos, N, base[MAXN], aft[MAXN], M, i ;
    int cnt, Len, T[MAXN << 5], L[MAXN << 5], R[MAXN << 5], sum[MAXN << 5] ;
    
    il int qr(){
        int k = 0, f = 1; 
        char c = getchar() ;
        while(!isdigit(c)){
            if (c == '-') f = -1 ;
            c = getchar() ;
        }
        while(isdigit(c)){
            k = (k << 1) + (k << 3) + c - 48 ;
            c = getchar() ;
        } 
        return k * f;
    }
    il int build(int l, int r){
        int rt = ++ cnt ;
        sum[rt] = 0 ;
        if(l < r){
            L[rt] = build(l, mid) ;
            R[rt] = build(mid + 1, r) ;
     	}
     	return rt;
    }
    il int update(int last, int l, int r, int x){
        int rt = ++ cnt ;
        sum[rt] = sum[last] + 1 ;
        R[rt] = R[last] ;
        L[rt] = L[last] ;
        if (l < r){
            if (x <= mid) L[rt] = update(L[last], l, mid, x) ;
            else  R[rt] = update(R[last], mid + 1, r, x) ;
        }
        return rt ;
    }
    il int query(int Left, int Right, int l, int r, int k){
        if (l == r) return l ;
        int x = sum[L[Right]] - sum[L[Left]], y = sum[R[Right]] - sum[R[Left]] ;
        if ((x << 1) > k) return query(L[Left], L[Right], l, mid, k) ;
        if((y << 1) > k) return query(R[Left], R[Right], mid + 1, r, k) ;
        return 0 ;
    }
    int main(){
        cin >> N >> M;
        for(i = 1; i <= N; i ++){
            base[i] = qr() ;
            aft[i] = base[i] ;
        }
        sort(aft + 1, aft + N + 1) ;
        Len = unique(aft + 1, aft + N + 1) - (aft + 1) ; 
        T[0] = build(1, Len) ;
        for(i = 1; i <= N; i ++){
            pos = lower_bound(aft + 1, aft + Len + 1, base[i]) - aft;
            T[i] = update(T[i - 1], 1, Len, pos) ;
        }
        for(i = 1; i <= M; i ++){
        	a = qr(), b = qr() ;
            printf("%d
    ", query(T[a - 1], T[b], 1, Len, b - a + 1)) ;
        }
    }
    

    还有,千万不要写错变量啊!!比如(Len)(N)搞混了之类的(QAQ)

  • 相关阅读:
    [node.js学习]为node.js写的一个操作mysql的类
    极光IM简单接入步骤
    windows自带的netsh 端口转发
    nodejs 做的带管理后台的东东,主要学习到 ....我忘了学到什么了
    利用来JS控制页面控件显示和隐藏有两种方法
    phpstudy 出现You don't have permission to access / on this server.
    禁用input自动填充
    一般充值的流程
    jq传输json字符串
    ECSHOP更改后台顶部图片
  • 原文地址:https://www.cnblogs.com/pks-t/p/9235668.html
Copyright © 2011-2022 走看看