树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)

Posted congmingyige

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)相关的知识,希望对你有一定的参考价值。

前提是数的范围较小

 1 数据范围:O(n) 
 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i)
 3 添加:log(n) (树状数组)
 4 删除:log(n) (树状数组)

团体程序设计天梯赛 L3-002. 堆栈

 1 /*数据范围:O(n) 
 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i)
 3 添加:log(n) (树状数组)
 4 删除:log(n) (树状数组)
 5 */ 
 6 #include <cstdio>
 7 #include <cstdlib>
 8 #include <cmath>
 9 #include <cstring>
10 #include <set>
11 #include <vector>
12 #include <stack>
13 #include <map>
14 #include <queue>
15 #include <algorithm>
16 #include <iostream>
17 using namespace std;
18 #define maxn 100000
19 
20 long a[100005];
21 long st[100005];
22 
23 int main()
24 {
25     long n,d,l,r,mid,i,g,c=0;
26     char s[20];
27     for (i=0;i<=maxn;i++)
28         a[i]=0;
29     scanf("%ld",&n);
30     while (n)
31     {
32         n--;
33         scanf("%s",s);
34         if (strcmp(s,"Pop")==0)
35         {
36             if (c==0)
37             {
38                 printf("Invalid\n");
39                 continue;
40             }    
41             d=st[c];
42             printf("%ld\n",d);
43             while (d<=maxn)
44             {
45                 a[d]--;
46                 d+=(d & (-d));
47             }
48             c--;
49         }
50         else if (strcmp(s,"Push")==0)
51         {
52             scanf("%ld",&d);
53             c++;
54             st[c]=d;            
55             while (d<=maxn)
56             {
57                 a[d]++;
58                 d+=(d & (-d));
59             }
60         }
61         else
62         {
63             d=(c+1)>>1;
64             if (c==0)
65             {
66                 printf("Invalid\n");
67                 continue;                
68             }
69             l=1; r=maxn;
70             while (l<=r)
71             {
72                 mid=(l+r)>>1;
73                 g=0;
74                 i=mid;
75                 while (i>=1)
76                 {
77                     g+=a[i];
78                     i-=(i & (-i));
79                 }
80                 if (g>=d)
81                     r=mid-1;
82                 else
83                     l=mid+1;
84             }
85             printf("%ld\n",l);
86         }
87     }
88     return 0;
89 }

 

以上是关于树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

bzoj3110[Zjoi2013]K大数查询 整体二分+树状数组区间修改

关于求解区间第k大的在线和离线做法

51Nod 1105 第K大的数 二分答案

1105 第K大的数(二分)

EC R 87 div2 D. Multiset 线段树 树状数组 二分