zoukankan      html  css  js  c++  java
  • HDU 5249 离线树状数组求第k大+离散化

    KPI

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1160    Accepted Submission(s): 488


    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
     
    Source
    题意: 三种操作 ”in  x“ 将x 加入到队列
                          ”out“ 删除队头元素
                          ”query“ 队列中现有元素升序排列后 输出第 ( len/2+1) 大元素
    题解:1.将所有元素离散化处理 这里的方法比较麻烦 具体看代码有多次映射
             2.根据操作  将离散化后的元素加入 树状数组 in~add(x,1),out~add(x,-1);
             3.树状数组求第k大 
             f[n] 树状数组
             f[1]=a1
             f[2]=a1+a2
             f[3]=a3
     
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<map>
      5 #include<algorithm>
      6 #include<stack>
      7 #include<queue>
      8 using namespace std;
      9 struct node
     10 {
     11     int x;
     12     int y;
     13 } s[10005];
     14 int t;
     15 int jishu=0;
     16 char a[10005][50];
     17 int b[10005];
     18 int exm;
     19 int f[100005];
     20 int coun=0;
     21 map<int,int> mp;
     22 map<int,int> mpp;
     23 queue<int> st;
     24 int n;
     25 bool cmp(struct node aa,struct node bb )
     26 {
     27     return aa.x<bb.x;
     28 }
     29 void add(int x,int y,int n) 
     30 {
     31         for (;x<=n;x+=x&(-x)) f[x]+=y;
     32 }
     33 int sum(int x) 
     34 {
     35         int ret=0;
     36         for (;x;x-=x&(-x)) ret+=f[x];
     37         return ret;
     38 }
     39 int find_k(int k) //求第k大 板子
     40 {
     41         int i,w=0;
     42         for (i=20;i>=0;i--)
     43         if (w+(1<<i)<=n&&f[w+(1<<i)]<k) 
     44         {
     45             k-=f[w+(1<<i)];w+=1<<i;
     46         }
     47         return w+1;
     48 }
     49 int k_num(int k){  
     50     int w=0,cnt=0;  
     51     for(int i=20;i>=0;i--)
     52     {  
     53         
     54         w+=(1<<i); 
     55         if(w>n || k<=f[w]) 
     56         w-=(1<<i);  
     57         else
     58          {
     59           k-=f[w];  
     60          }
     61     }  
     62     return w+1;  
     63 }  
     64 int main()
     65 {   
     66        while(scanf("%d",&t)!=EOF)
     67 {       jishu++;
     68         memset(s,0,sizeof(s));
     69         memset(a,0,sizeof(a));
     70         memset(b,0,sizeof(b));
     71         memset(f,0,sizeof(f));
     72         mp.clear();
     73         mpp.clear();
     74         while(st.size()>0)
     75          st.pop();
     76     coun=0;
     77     for(int i=1;i<=t;i++)
     78     {
     79         scanf("%s",&a[i]);
     80         if(a[i][0]=='i')
     81         { 
     82             scanf("%d",&exm);
     83             s[++coun].x=exm;//存插入的元素
     84             s[coun].y=coun;//struct 存储对应位置
     85         }
     86     }
     87     cout<<"Case #"<<jishu<<":"<<endl;
     88     sort(s+1,s+1+coun,cmp);//结构体排序 x为主键升序排列
     89     b[s[1].y]=1;
     90     int k=1;
     91      mp[s[1].x]=1;
     92      mpp[1]=s[1].x;
     93     for(int i=2;i<=coun;i++)//for循环完成离散化处理
     94     {
     95         if(s[i].x==s[i-1].x)
     96          {
     97           b[s[i].y]=k;
     98           mp[s[i].x]=k;// 与元素的相互映射
     99           mpp[k]=s[i].x;//
    100          }
    101         else
    102          {
    103          b[s[i].y]=++k;    
    104          mp[s[i].x]=k;
    105          mpp[k]=s[i].x;
    106          }
    107     }
    108     n=k;
    109     k=0;
    110     for(int i=1;i<=t;i++)
    111     {
    112        if(a[i][0]=='i')
    113         {
    114             st.push(mpp[b[++k]]);
    115             add(b[k],1,n);
    116         }
    117         if(a[i][0]=='o')
    118       {
    119          int now=st.front();
    120          st.pop();
    121          add(mp[now],-1,n);
    122       }
    123       if(a[i][0]=='q')
    124       {
    125            int len=st.size();
    126            int location=k_num((len/2)+1);
    127            printf("%d
    ",mpp[location]);
    128            
    129       }  
    130     }    
    131 }
    132     return 0;
    133 } 
    134 /*
    135 10
    136 in 3
    137 in 1
    138 out
    139 in 4
    140 query
    141 in 2
    142 out
    143 in 100
    144 in 1
    145 query
    146 */
     
     
  • 相关阅读:
    写代码的方法与思考
    改变文件上传input file类型的外观
    关于HTML Button点击自动刷新页面的问题解决
    使用 git push 出现error setting certificate verify locations问题记录
    flex使用学习
    jQuery.fn.extend()
    jQuery extend()
    作用域
    私有变量
    模仿块级作用域
  • 原文地址:https://www.cnblogs.com/hsd-/p/5338954.html
Copyright © 2011-2022 走看看