• [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)

  • 相关阅读:
    微软 软件的 一组堆成快捷键
    C#事件 的讲解
    软件缺陷分析的几种方法
    一个长三角人对深圳的看法 (转)
    一次LoadRunner的CPC考试经历
    测试是一门武功
    ORACLE的性能测试经验总结
    深圳测试协会第九次论坛在深圳举行
    10月28日参加了IBM的产品推介会
    什么是web安全性测试?
  • 原文地址:https://www.cnblogs.com/pks-t/p/9235668.html
Copyright © 2020-2023  润新知