HDU 5249 离线树状数组求第k大+离散化

Posted 半根毛线code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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 */

 

 
 

以上是关于HDU 5249 离线树状数组求第k大+离散化的主要内容,如果未能解决你的问题,请参考以下文章

*HDU2852 树状数组(求第K小的数)

[hdu 4417]树状数组+离散化+离线处理

利用id来进行树状数组,而不是离散化以后的val HDU 4417 离线+树状数组

树状数组求第K大(From CLJ)

HDU 5877 Weak Pair(树状数组+dfs+离散化)

HDU 5877 Weak Pair DFS + 树状数组 + 其实不用离散化