zoukankan      html  css  js  c++  java
  • [HNOI2002]营业额统计 II

    https://www.luogu.org/problemnew/show/2234

    将权值离散化,以权值为下标建立权值线段树

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 32780;
    const int oo = 999999999;
    
    #define gc getchar()
    #define lson jd << 1
    #define rson jd << 1 | 1
    
    struct Node_1 {int data, id;} A[N];
    struct Node_2 {int l, r, w, Max, Min;} T[N << 2];
    int Ask[N], n, Answer, D[N], before, after;
    
    inline int read(){
        int x = 0, f = 1; char c = gc;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc;}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x * f;
    }
    
    bool cmp(Node_1 a, Node_1 b) {return a.data < b.data;}
    
    void pushup(int jd){
        T[jd].w = T[lson].w + T[rson].w;
        T[jd].Max = max(T[lson].Max, T[rson].Max);
        T[jd].Min = min(T[lson].Min, T[rson].Min); 
    }
    
    void build_tree(int l, int r, int jd){
        T[jd].l = l; T[jd].r = r; T[jd].Min = oo - 1; T[jd].Max = -1;
        if(l == r) return ;
        int mid = (l + r) >> 1;
        build_tree(l, mid, lson);
        build_tree(mid + 1, r, rson);    
    }
    
    void Poi_G(int l, int r, int jd, int x){
        if(l == r) {T[jd].w = 1; T[jd].Max = l; T[jd].Min = l; return ;}
        int mid = (l + r) >> 1;
        if(x <= mid) Poi_G(l, mid, lson, x);
        else Poi_G(mid + 1, r, rson, x);
        pushup(jd);
    }
    
    void Sec_Min(int l, int r, int jd, int x, int y){
        if(!T[jd].w) return ;
        if(x <= l && r <= y) {after = min(after, T[jd].Min); return ;}
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_Min(l, mid, lson, x, y);
        if(y > mid)  Sec_Min(mid + 1, r, rson, x, y); 
    }
    
    void Sec_Max(int l, int r, int jd, int x, int y){
        if(!T[jd].w) return ;
        if(x <= l && r <= y) 
        {before = max(before, T[jd].Max); return ;}
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_Max(l, mid, lson, x, y);
        if(y > mid)  Sec_Max(mid + 1, r, rson, x, y);
    }
    
    int main()
    {
        n = read();
        for(int i = 1; i <= n; i ++) {A[i].data = read(); A[i].id = i;}
        sort(A + 1, A + n + 1, cmp);//按照权值进行排序
        Ask[A[1].id] = 1; D[1] = A[1].data; int Id = 2;//第i次访问的那个点在线段树中的位置
        for(int i = 2; i <= n; i ++){
            if(A[i].data == A[i - 1].data) continue ;
            Ask[A[i].id] = Id; D[Id] = A[i].data;//线段树中位置对应的点的权值
            Id ++;
        }
        Id --;
        build_tree(1, Id, 1);//建树
        Answer += D[Ask[1]];//第1次访问的点在线段树中的位置所对应的权值
        Poi_G(1, Id, 1, Ask[1]);
        for(int i = 2; i <= n; i ++){
            if(!Ask[i]) continue ;
            before = - oo, after = oo;
            Sec_Max(1, Id, 1, 1, Ask[i]);
            Sec_Min(1, Id, 1, Ask[i] + 1, Id);
            if(before == - oo) Answer += D[after] - D[Ask[i]];
            else if(after == oo) Answer += D[Ask[i]] - D[before];
            else Answer += min(abs(D[Ask[i]] - D[before]), abs(D[Ask[i]] - D[after]));
            Poi_G(1, Id, 1, Ask[i]);
        }
        cout << Answer;
        return 0;
    }
  • 相关阅读:
    关于异步取消线程以及异步销毁锁的探讨
    pthread_mutex_init & 互斥锁pthread_mutex_t的使用(转)
    Qt设置全局的widget的stylesheet
    浅析pthread_cond_wait(转)
    575 Skew Binary
    HDU 1229 还是A+B
    10370
    10300
    UVA 10071 Problem B Back to High School Physics
    UVA 10055 Problem A Hashmat the brave warrior
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8177982.html
Copyright © 2011-2022 走看看