zoukankan      html  css  js  c++  java
  • HDU 5249:KPI(权值线段树)

    KPI

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


    Problem Description
    你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度。数十亿的请求被推到一个大管道后同时服务从管头拉取请求。让我们来定义每个请求都有一个重要值。我的KPI是由当前管道内请求的重要值的中间值来计算。现在给你服务记录,有时我想知道当前管道内请求的重要值得中间值。
     
    Input
    有大约100组数据。

    每组数据第一行有一个n(1n10000),代表服务记录数。

    接下来有n行,每一行有3种形式
      "in x": 代表重要值为x(0x109)的请求被推进管道。
      "out": 代表服务拉取了管道头部的请求。
      "query: 代表我想知道当前管道内请求重要值的中间值. 那就是说,如果当前管道内有m条请求, 我想知道,升序排序后第floor(m/2)+1th 条请求的重要值.

    为了让题目简单,所有的x都不同,并且如果管道内没有值,就不会有"out"和"query"操作。
     
    Output
    对于每组数据,先输出一行

    Case #i:
    然后每一次"query",输出当前管道内重要值的中间值。
     
    Sample Input
    6
    in 874
    query
    out
    in 24622
    in 12194
    query
     
    Sample Output
    Case #1:
    874
    24622
     

    算法:权值线段树

    题解:此题需要先离散化,然后根据权值线段树的特点,依次更新每个区间数的个数,然后根据个数查询即可,题中的拉取了管道头部,直接用队列模拟就好。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5+7;
    
    struct query {
        int op;
        int val;
    }Q[maxn];
    
    struct tree {
        int l, r, s;
    }tree[maxn << 2];
    
    
    vector<int> v;
    int n;
    int len;
    
    int find(int x) {
        return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
    }
    
    void init() {
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        len = v.size();
    }
    
    void build(int root, int l, int r) {
        tree[root].l = l;
        tree[root].r = r;
        tree[root].s = 0;
        if(l == r) {
            return;
        }
        int mid = (l + r) >> 1;
        build(root << 1, l, mid);
        build(root << 1 | 1, mid + 1, r);
    }
    
    void update(int root, int pos, int val) {
        int l = tree[root].l;
        int r = tree[root].r;
        tree[root].s += val;
        if(l == r) {
            return;
        }
        int mid = (l + r) >> 1;
        if(pos <= mid) {
            update(root << 1, pos, val);
        } else {
            update(root << 1 | 1, pos, val);
        }
    }
    
    int query(int root, int k) {
        int l = tree[root].l;
        int r = tree[root].r;
        if(l == r) {
            return l;
        }
        int sum = tree[root << 1].s;
        if(sum >= k) {
            return query(root << 1, k);
        } else {
            return query(root << 1 | 1, k - sum);
        }
    }
    
    int main() {
        int cas = 0;
        while(~scanf("%d", &n)) {
            for(int i = 1; i <= n; i++) {
                char str[10];
                scanf("%s", str);
                if(str[0] == 'i') {
                    Q[i].op = 1;
                    scanf("%d", &Q[i].val);
                    v.push_back(Q[i].val);
                } else if(str[0] == 'o') {
                    Q[i].op = 2;
                } else {
                    Q[i].op = 3;
                }
            }
            init();
            build(1, 1, len);
            queue<int> que;     //此队列模拟进出数据
            printf("Case #%d:
    ", ++cas);
            for(int i = 1; i <= n; i++) {
                if(Q[i].op == 1) {
                    int pos = find(Q[i].val);
                    update(1, pos, 1);
                    que.push(pos);      
                } else if(Q[i].op == 2) {
                    update(1, que.front(), -1);
                    que.pop();
                } else {
                    int k = (que.size() / 2) + 1;
                    int pos = query(1, k);
                    printf("%d
    ", v[pos - 1]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    iOS SpriteKit 字体设置无效问题
    2021又来到了!
    其他人员优点
    自己缺点记录
    领导优点分析-于总
    领导优点分析-黄总
    Linux CentOS 7 安装字体库 & 中文字体
    mysql备份数据库
    MySQL mysqldump 导入/导出 结构&数据&存储过程&函数&事件&触发器
    mysql 导入导出数据库以及函数、存储过程的介绍
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/11287074.html
Copyright © 2011-2022 走看看